स्विफ्ट 3 - डिवाइस टोकन अब '32BYTES' के रूप में पार्स किए जा रहे हैं


94

मैंने अभी Xcode 7 से 8 GM तक अपडेट किया और स्विफ्ट 3 संगतता समस्याओं के बीच मैंने देखा कि मेरे डिवाइस टोकन ने काम करना बंद कर दिया है। वे अब केवल '32BYTES' पढ़ते हैं।

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
    print(deviceToken) // Prints '32BYTES'
    print(String(data: deviceToken , encoding: .utf8)) // Prints nil
}

अपडेट से पहले मैं एनएसडाटा को केवल अपने सर्वर पर भेजने में सक्षम था, लेकिन अब मुझे एक कठिन समय वास्तव में टोकन को पार्स करने में है।

मुझे यहां क्या समझ नहीं आ रहा है?

संपादित करें: मैं अभी NSData में परिवर्तित कर रहा हूं और अपेक्षित परिणाम देख रहा हूं। तो अब मैं नए डेटा प्रकार के बारे में उलझन में हूँ।

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
    print(deviceToken) // Prints '32BYTES'
    print(String(data: deviceToken , encoding: .utf8)) // Prints nil

    let d = NSData(data: deviceToken)
    print(d) // Prints my device token
}

2
करने के लिए बदल रहा है NSDataबस प्रिंट descriptionकी NSData। आप अभी भी उस से एक तार नहीं मिलता है।
रामप्यारी

जवाबों:


189
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    print(token)
}

उलटा ऑपरेशन (हेक्स स्ट्रिंग -> डेटा) यहां उपलब्ध है: stackoverflow.com/a/46663290/5252428
Rok ग्रेगोरीक

4
%02xठीक भी है।
jqgsninimo

1
@ क्या आप अपना उत्तर बता सकते हैं? टोकन का प्रारूपित किया गया नया प्रारूप क्या है?
सिमो

@simo यह डेटा से हेक्साडेसिमल स्ट्रिंग में रूपांतरण है जिसे आप पुश सूचना भेजने में सक्षम होने के लिए एक वेब सेवा / एपीआई में पास कर सकते हैं।
रोक ग्रेगोरी

के बीच मतभेद का एक अच्छा विवरण के साथ एक अच्छा पद %02.2hhxऔर %02x nshipster.com/apns-device-tokens/#overturned-in-ios-13
रोक Gregorič

35

मुझे भी यही समस्या थी। यह मेरा समाधान है:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    var token = ""
    for i in 0..<deviceToken.count {
        token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
    }
    print(token)
}

1
यह NSDataएक स्ट्रिंग में एन्कोडिंग के लिए एक वैकल्पिक दृष्टिकोण है । मैंने अपने जवाब में बेस 64 एनकोडिंग का उपयोग करने का सुझाव दिया। यह बेस 16 एन्कोडिंग का उपयोग करता है।
रामप्यारी

@ अपने तरीके से भी दिलचस्प है लेकिन यह अधिक उपयोगी होगा यदि आप हमें कोड के साथ कुछ मार्गदर्शन दे !!!
विवेक अग्रवाल

29

यहाँ मेरा स्विफ्ट 3 एक्सटेंशन है बेस -16 एनकोडेड हेक्स स्ट्रिंग पाने के लिए:

extension Data {
    var hexString: String {
        return map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
    }
}

मैंने देखा है कि "% 02x" प्रारूप भी काम करता है। मैं यह भी नहीं समझ सकता कि "hh" क्या करता है
andrei

1
@andrei "hh" इनपुट के इलाज के लिए स्ट्रिंग फ़ॉर्मेटर को एक चार के रूप में बताता है। हालांकि स्विफ्ट में, डेटा UInt8 का संग्रह है, इसलिए आपको इसकी आवश्यकता नहीं है
20:29 पर wyu

27

डिवाइस टोकन कभी भी एक स्ट्रिंग नहीं है और निश्चित रूप से UTF-8 एन्कोडेड स्ट्रिंग नहीं है। यह डेटा है। यह अपारदर्शी डेटा के 32 बाइट्स है।

अपारदर्शी डेटा को एक स्ट्रिंग में बदलने का एकमात्र वैध तरीका है, इसे एनकोड करना - आमतौर पर बेस 64 एन्कोडिंग के माध्यम से।

स्विफ्ट 3 / iOS 10 में, बस Data base64EncodedString(options:)विधि का उपयोग करें ।


वैसे यहाँ अंतर नया डेटा प्रकार है। मैंने अभी डिवाइसटोकन को NSData में बदलने की कोशिश की है और अब यह मेरे डिवाइस टोकन को पहले की तरह प्रिंट करता है। क्या आपके पास एक उदाहरण है कि आप NSData के बिना इससे कैसे निपटेंगे? क्योंकि यह हैकिंग महसूस करता है, लेकिन जितना वे हमसे उम्मीद करते हैं उससे कहीं ज्यादा सीधा और सरल है।
user1537360

3
मैंने जो कहा मैं उसपर अडिग हूँ। NSDataया Data, इससे कोई फर्क नहीं पड़ता। डेटा के बाइट्स एक स्ट्रिंग नहीं हैं और कभी नहीं हुए हैं। प्रलेखन में स्पष्ट रूप से कहा गया है कि यह डेटा का एक अपारदर्शी सेट है। यह तथ्य कि आपका कोड काम करता था, भाग्य है। यह हमेशा इसे संभालने का गलत तरीका था। बस डेटा को बेस 64 एन्कोडिंग द्वारा डेटा को स्ट्रिंग में परिवर्तित करें। यह अब और पहले उचित समाधान है।
रामप्यारी

यदि आप किसी सेवा जैसे Amazon SNS का उपयोग करते हैं, तो Base64 डिकोडिंग काम नहीं करता है। समाधान जो डेटा को हेक्साडेसिमल वर्णों में परिवर्तित करते हैं, जैसे कि @ सत्थेश्वरन , डिवाइस टोकन स्ट्रिंग्स का उत्पादन करते हैं जो एसडीके में बदलाव से पहले लोगों से मिलते जुलते हैं।
अलेक्जेंडर

@Alexander Base64 डिकोडिंग के बारे में किसने कुछ कहा? प्रश्न और उत्तर के पूरे बिंदु को एक स्ट्रिंग में कच्चे डेटा को एनकोड करना है, न कि डिकोड करना। इसका कोई भी कारण कच्चे डेटा को देखने का एकमात्र कारण है। विशिष्ट एन्कोडिंग योजना अप्रासंगिक है। अन्य उत्तर बेस 16 एन्कोडिंग का उपयोग कर रहा है। मैंने बेस 64 एनकोडिंग का उपयोग करने का उल्लेख किया है।
रामप्यारी

@rmaddy का मतलब था मेरी टिप्पणी में बेस 64 एनकोडिंग, मेरी माफी।
अलेक्जेंडर

15

इसे इस्तेमाल करे:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

   let token = String(data: deviceToken.base64EncodedData(), encoding: .utf8)?.trimmingCharacters(in: CharacterSet.whitespaces).trimmingCharacters(in: CharacterSet(charactersIn: "<>")) 
}

2
ऐसा लगता है कि अब यह अलग टोकन लौटाता है
चिकबुज़

8

इसे इस्तेमाल करे

if #available(iOS 10.0, *) {
   let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
}

7

स्विफ्ट 3

सबसे अच्छा और आसान तरीका।

deviceToken.base64EncodedString()

3
यह सबसे आसान है, लेकिन सावधान रहें कि यदि आप टोकन बंद कर रहे हैं तो आपका सर्वर क्या उपयोग कर रहा है। कई एपीआई हेक्स एन्कोडेड या बेस -16 के साथ उम्मीद करते हैं। उदाहरण के लिए, Django पुश सूचनाएं।
sww314

4

यह एक आधिकारिक उत्तर के रूप में नहीं कहा गया था (इसे एक टिप्पणी में देखा), लेकिन मैंने अंततः अपने टोकन को वापस पाने के लिए क्या किया।

let tokenData = deviceToken as NSData
let token = tokenData.description

// remove any characters once you have token string if needed
token = token.replacingOccurrences(of: " ", with: "")
token = token.replacingOccurrences(of: "<", with: ""
token = token.replacingOccurrences(of: ">", with: "")

हमारे बैकएंड एपीआई (पायथन) के उद्देश्यों के लिए, यह "स्वच्छतम" समाधान _ \ _ (¯) _ / ツ
race_carr

1
यह iOS 10 में काम नहीं करता है। अब विवरण केवल "32bytes" पर लौटता है।
एडोपेलवी

@edopelawi आप as NSDataवहाँ रखना भूल गए । जब आप NSData नहीं डेटा के रूप में डाल दिया iOS 10 पर भी सही मूल्य वापस आ जाएगा
Jakub

4
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let token = deviceToken.map({ String(format: "%02.2hhx", $0)}).joined()
     print("TOKEN: " + token)


}

4
हालांकि यह कोड ब्लॉक प्रश्न का उत्तर दे सकता है, यह सबसे अच्छा होगा यदि आप ऐसा करने के लिए थोड़ा स्पष्टीकरण प्रदान कर सकते हैं।
क्रिस्पिन

3

मैंने बस यही किया,

let token = String(format:"%@",deviceToken as CVarArg).components(separatedBy: CharacterSet.alphanumerics.inverted).joined(separator: "")

इसने जैसा परिणाम दिया,

let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()

0

उचित प्रारूप के साथ डिवाइस टोकन प्राप्त करें।

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) 
{
            var formattedToken = ""
            for i in 0..<deviceToken.count {
                formattedToken = formattedToken + String(format: "%02.2hhx", arguments: [deviceToken[i]])
            }
            print(formattedToken)
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.