সুইফ্ট 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
}

আপডেটের আগে আমি সহজেই আমার সার্ভারে এনএসডিটা প্রেরণ করতে সক্ষম হয়েছি, তবে এখন টোকনটি পার্স করতে আসলে আমার খুব কষ্ট হচ্ছে।

আমি এখানে কি মিস করছি?

সম্পাদনা: আমি কেবল এনএসডিটাতে ফিরে রূপান্তর করার পরীক্ষা করছি এবং আমি প্রত্যাশিত ফলাফলগুলি দেখছি। সুতরাং এখন আমি নতুন তথ্য টাইপ সম্পর্কে বিভ্রান্ত করছি।

    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
}

4
পরিবর্তন NSDataকেবল ছাপে descriptionএর NSData। আপনি এখনও থেকে স্ট্রিং পাবেন না।
rmaddy

উত্তর:


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 Gregorič

4
%02xঠিক আছে।
jqgsninimo

4
@ রোক আপনি কি আপনার উত্তরটি ব্যাখ্যা করতে পারেন? টোকেনটি কী নতুন বিন্যাসে ফর্ম্যাট হয়েছিল?
সিমো

@ সিমো এটি ডেটা থেকে হেক্সাডেসিমাল স্ট্রিংয়ে রূপান্তর যা আপনি কোনও ওয়েব সার্ভিস / এপিআইতে পুশ বিজ্ঞপ্তি প্রেরণ করতে সক্ষম হওয়ার জন্য পাস করতে পারেন।
রক গ্রেগরিč


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)
}

4
NSDataস্ট্রিংটিতে এনকোডিংয়ের এটি বিকল্প বিকল্প । আমি আমার উত্তরে বেস 64 এনকোডিং ব্যবহার করার পরামর্শ দিয়েছি। এটি বেস 16 এনকোডিং ব্যবহার করে।
rmaddy

@ আরমডি আপনার উপায়টিও আকর্ষণীয় তবে আপনি যদি কোড সহ আমাদের কিছু গাইডেন্স দেন তবে এটি আরও সহায়ক হবে !!!
বিবেক অগ্রবত

29

বেস -16 এনকোডড হেক্স স্ট্রিংটি পেতে এখানে আমার সুইফট 3 এক্সটেনশনটি রয়েছে:

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

আমি লক্ষ্য করেছি যে "% 02x" ফর্ম্যাটটিও কাজ করে। "Hh" কী করে তা আমি বুঝতেও পারি না
Andrei

4
@ এন্ড্রেই "এইচএইচ" স্ট্রিং বিন্যাসকে ইনপুটটিকে চর হিসাবে বিবেচনা করে বলে। তবে দ্রুতগতিতে ডেটা ইউআইএনটি 8 এর সংগ্রহ, সুতরাং আপনার এটির দরকার নেই
উইউ

27

ডিভাইস টোকেন কখনও স্ট্রিং ছিল না এবং অবশ্যই কোনও ইউটিএফ -8 এনকোডেড স্ট্রিং নয়। এটি ডেটা। এটি অস্বচ্ছ ডেটা 32 বাইট।

অস্বচ্ছ ডেটা স্ট্রিংয়ে রূপান্তর করার একমাত্র বৈধ উপায় হ'ল এটিকে এনকোড করা হয় - সাধারণত একটি বেস 64 এনকোডিংয়ের মাধ্যমে।

সুইফ্ট 3 / আইওএস 10 এ, কেবল Data base64EncodedString(options:)পদ্ধতিটি ব্যবহার করুন ।


ঠিক এখানে পার্থক্যটি নতুন ডেটা টাইপ। আমি কেবলমাত্র টোকেন ডিভাইসটিকে এনএসটাটাতে রূপান্তর করার চেষ্টা করেছি এবং এটি এখন আমার ডিভাইস টোকেনটিকে ঠিক আগের মতো মুদ্রণ করে। এনএসডিটা না করে আপনি কীভাবে এটি মোকাবেলা করবেন তার উদাহরণ রয়েছে? কারণ এটি হ্যাকিং অনুভব করে তবে তারা আমাদের কাছ থেকে যা প্রত্যাশা করে বলে মনে হয় তার চেয়ে আরও সরল।
ব্যবহারকারী 1537360

4
আমি যা বলেছি তার পাশে দাঁড়িয়েছি। NSDataবা Data, এটা কোন ব্যাপার না। ডেটার বাইটগুলি স্ট্রিং হয় না এবং কখনও হয় না। ডকুমেন্টেশনটি পরিষ্কারভাবে জানিয়েছে যে এটি ডেটাগুলির একটি অস্বচ্ছ সেট। আপনার কোডটি কাজ করত তা ভাগ্য is এটি পরিচালনা করার জন্য এটি সর্বদা ভুল উপায় ছিল। কেবলমাত্র বেস কে 64 এটি এখন এবং আগে সঠিক সমাধান।
rmaddy

আপনি যদি অ্যামাজন এসএনএসের মতো পরিষেবা ব্যবহার করেন তবে বেস 64 ডিকোডিং কাজ করে না। সমাধানগুলি যা ডেটাটিকে হেক্সাডেসিমাল অক্ষরগুলিতে রূপান্তর করে, যেমন @ সাথেশ্বরান এর ডিভাইস টোকেন স্ট্রিং তৈরি করে যা এসডিকে পরিবর্তনের আগে এর অনুরূপ।
আলেকজান্ডার

@ আলেকজান্দার বেস 64 ডিকোডিং সম্পর্কে কে কিছু বলেছেন? প্রশ্নের পুরো উত্তর এবং উত্তর হ'ল কাঁচা ডেটা এনকোড করা , ডিকোড নয়, একটি স্ট্রিংয়ে। এগুলির যে কোনও একটিই করার একমাত্র কারণ হ'ল কাঁচা ডেটা। নির্দিষ্ট এনকোডিং প্রকল্পটি অপ্রাসঙ্গিক। অন্য উত্তরটি বেস 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: "<>")) 
}

4
দেখে মনে হচ্ছে এখন এটি আলাদা টোকেন দেয়
চিকাবুজেড

8

এটা চেষ্টা কর

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

7

সুইফট 3

সবচেয়ে ভাল এবং সহজ উপায়।

deviceToken.base64EncodedString()

4
এটি সবচেয়ে সহজ, তবে আপনি যদি টোকেনটি বন্ধ করে দিচ্ছেন তবে আপনার সার্ভারটি কী ব্যবহার করছে তা সাবধান হন। অনেকগুলি এপিএস হেক্স এনকোডযুক্ত বা বেস -16 এর সাথে প্রত্যাশা করে। উদাহরণস্বরূপ, জ্যাঙ্গো পুশ বিজ্ঞপ্তি।
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: "")

আমাদের ব্যাকএন্ড এপিআই (পাইথন) এর উদ্দেশ্যে, এটি "পরিষ্কার" সমাধান হিসাবে শেষ হয়েছে ¯ \ _ (ツ) _ / ¯
রেস_সিয়ার

4
এটি আইওএস ১০ এ কাজ করে না The বর্ণনায় এখন কেবলমাত্র "32 বাইটস" ফিরে আসে।
এডোপ্লেভী

@ ইডোপ্লেভী আপনি as NSDataসেখানে রাখতে ভুলে গেছেন । আপনি যখন এনএসডিটা হিসাবে রাখেন না তখন ডেটা আইওএস 10 তেও সঠিক মান ফিরে আসবে
জাকব

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)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.