ฉันจะแปลงโทเค็นอุปกรณ์ของฉัน (NSData) เป็น NSString ได้อย่างไร


157

ฉันกำลังใช้การแจ้งเตือนแบบพุช ฉันต้องการบันทึก APNS Token ของฉันเป็นสตริง

- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken
{
    NSString *tokenString = [NSString stringWithUTF8String:[newDeviceToken bytes]]; //[[NSString alloc]initWithData:newDeviceToken encoding:NSUTF8StringEncoding];
    NSLog(@"%@", tokenString);
    NSLog(@"%@", newDeviceToken);
}

บรรทัดแรกของรหัสพิมพ์ null วินาทีพิมพ์โทเค็น ฉันจะรับอุปกรณ์ใหม่เปิดเป็น NSString ได้อย่างไร


เอาต์พุตของวินาทีที่สองคืออะไรNSLogที่พิมพ์ออกมาnewDeviceToken?
rob mayoff


อย่าใช้คำอธิบาย
Fattie

คำตอบ:


40

ใช้สิ่งนี้:

NSString * deviceTokenString = [[[[deviceToken description]
                         stringByReplacingOccurrencesOfString: @"<" withString: @""] 
                        stringByReplacingOccurrencesOfString: @">" withString: @""] 
                       stringByReplacingOccurrencesOfString: @" " withString: @""];

NSLog(@"The generated device token string is : %@",deviceTokenString);

134
ดูเหมือนจะเป็นความคิดที่ดีที่จะใช้คำอธิบาย: ไม่มีสิ่งใดรับประกันได้ว่า iOS รุ่นที่ใหม่กว่าจะไม่เปลี่ยนการใช้งานและผลลัพธ์ของการโทรนี้
madewulf

16
อันที่จริงนี่เป็นความคิดที่แย่จริงๆ
David Snabel-Caunt

21
@madewulf เป็นคนดีมากที่จะชี้ให้เห็นว่ามันช่างเป็นความคิดที่แย่มากที่จะใช้คำอธิบาย .. มันคงจะดีกว่านี้ถ้าคุณแนะนำทางเลือกอื่น ๆ
abbood

6
วิธีแก้ปัญหาที่นี่ภายใต้ [deviceToken bytes] ตรงกับบิล
madewulf

37
ปรากฎเป็น Swift 3 / iOS 10 คำอธิบายบนอุปกรณ์โทเค็นส่งคืน "32 ไบต์" ดังนั้นใช่อย่าใช้สิ่งนี้
Victor Luft

231

หากใครกำลังมองหาวิธีการทำเช่นนี้ใน Swift:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
    var tokenString = ""

    for i in 0..<deviceToken.length {
        tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
    }

    print("tokenString: \(tokenString)")
}

แก้ไข: สำหรับ Swift 3

Swift 3 แนะนำDataประเภทโดยมีความหมายตามตัวอักษร ในการแปลงdeviceTokenเป็นสตริงคุณสามารถทำได้ดังนี้:

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

118
ทำไมสิ่งนี้ถึงต้องมีความซับซ้อนเช่นนี้เกิดอะไรขึ้นกับระบบปฏิบัติการที่ให้สายอักขระแก่เราเนื่องจากเป็นสิ่งที่ทุกคนต้องการ ขอบคุณสำหรับการแก้ปัญหานี้
Piwaf

3
@Sascha ฉันหวังว่าคุณเห็นด้วยกับการแก้ไขของฉันไปที่คำตอบที่มีประโยชน์มากของคุณ :)
jrturton

16
ฉันได้รับการปรับปรุงใหม่: let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined() qiita.com/mono0926/items/3cf0dca3029f32f54a09
โมโน

2
ฉันไม่แนะนำให้ใช้คำอธิบายเนื่องจากไม่รับประกันว่าจะมีเสถียรภาพ ลองดูคำตอบของฉันที่นี่: stackoverflow.com/questions/9372815/…
swift taylor

7
คุณช่วยอธิบายว่า"%02.2hhxทำอะไรได้บ้าง
ฮันนี่

155

มีคนช่วยฉันด้วยสิ่งนี้ฉันแค่ผ่านไป

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {

    const unsigned *tokenBytes = [deviceToken bytes];
    NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                         ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                         ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                         ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];

    [[MyModel sharedModel] setApnsToken:hexToken];
}

5
นี่คือทางออกที่ดีที่สุดตั้งแต่ encondig ไบต์เป็น hex, หมายความว่าคุณสามารถนับมัน;)
loretoparisi

4
บน XCode 5 ฉันต้องใช้การโยนอุปกรณ์เพื่อทำการคอมไพล์: const unsigned * tokenBytes = (const unsigned *) [deviceToken bytes];
Ponytech

3
โทเค็นจะมีขนาดใหญ่กว่า 32 ไบต์ในไม่ช้าดังนั้นจึงจำเป็นต้องวนซ้ำแต่ละไบต์แทนที่จะเป็นจำนวนเต็มแปดตัว
Tom Dalling

5
นี่จะเป็นทางออกที่ดีกว่าหรือไม่? const unsigned *tokenBytes = [deviceToken bytes]; NSMutableString *hexToken = [NSMutableString string]; for (NSUInteger byteCount = 0; byteCount * 4 < [deviceToken length]; byteCount++) { [hexToken appendFormat:@"%08x", ntohl(tokenBytes[byteCount])]; }
Harro

9
Important: APNs device tokens are of variable length. Do not hard-code their size.Apple พูดว่า
erkanyildiz

141

คุณสามารถใช้สิ่งนี้

- (NSString *)stringWithDeviceToken:(NSData *)deviceToken {
    const char *data = [deviceToken bytes];
    NSMutableString *token = [NSMutableString string];

    for (NSUInteger i = 0; i < [deviceToken length]; i++) {
        [token appendFormat:@"%02.2hhX", data[i]];
    }

    return [token copy];
}

11
descriptionนี้ควรจะเป็นคำตอบที่ได้รับการยอมรับตามที่มันเป็นวิธีที่ปลอดภัยมากกว่าการใช้
DrMickeyLauer

8
นี่เป็นคำตอบเดียวที่ถูกต้องใน Objective-C ที่จะจัดการกับการเพิ่มขึ้นของขนาดโทเค็น
Tom Dalling

ยอมรับว่านี่อาจเป็นวิธีที่ปลอดภัยที่สุดเนื่องจากจะไม่ถือว่าขนาด / ความยาวโทเค็นใด ๆ โดยเฉพาะ
Ryan H.

ใช้งานได้ใน iOS 10
Tjalsma

2
ฉันเคยใช้ [token appendFormat:@"%02.2hhx", data[i]];เป็น Amazon SNS ต้องใช้ตัวพิมพ์เล็ก
Manuel Schmitzberger

43

สำหรับผู้ที่ต้องการในSwift 3และวิธีการที่ง่ายที่สุด

func extractTokenFromData(deviceToken:Data) -> String {
    let token = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    return token.uppercased();
}

1
ฉันเขียนรหัสเดียวกัน :) นี่เป็นเวอร์ชั่นที่รวดเร็วที่สุดและใช้ได้เฉพาะงานนี้
Quver

1
@Anand คุณได้โปรดอธิบายสิ่งที่เกิดขึ้นในรหัสนี้deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
Ramakrishna

1
มันใช้ลดฟังก์ชั่นของ swift ที่ทำให้ข้อมูลเป็นอนุกรมสตริงเลขฐานสิบหกและจากนั้นไปยังสตริง เพื่อทำความเข้าใจเพิ่มเติมเกี่ยวกับฟังก์ชั่นลดการอ่านuseyourloaf.com/blog/swift-guide-to-map-filter-reduce
Anand

15

คำอธิบาย%02.2hhxในคำตอบการโหวตสูง:

  • %: แนะนำตัวxระบุการแปลง
  • 02: ความกว้างต่ำสุดของค่าที่แปลงแล้วคือ 2 หากค่าที่แปลงแล้วมีจำนวนไบต์น้อยกว่าความกว้างของเขตข้อมูลจะต้องถูกเพิ่มด้วย0ด้านซ้าย
  • .2: กำหนดจำนวนหลักขั้นต่ำที่จะปรากฏสำหรับตัวxระบุการแปลง
  • hh: ระบุว่าตัวxระบุการแปลงใช้กับอาร์กิวเมนต์ถ่านที่ลงนามแล้วหรือที่ไม่ได้ลงชื่อ (อาร์กิวเมนต์จะได้รับการเลื่อนตำแหน่งตามการเลื่อนเลขจำนวนเต็ม แต่ค่าของมันจะถูกแปลงเป็นถ่านที่ลงนามหรือถ่านที่ไม่ได้ลงชื่อก่อนพิมพ์)
  • x: อาร์กิวเมนต์ที่ไม่ได้ลงชื่อจะถูกแปลงเป็นรูปแบบเลขฐานสิบหกที่ไม่ได้ลงชื่อในสไตล์ "dddd"; ใช้ตัวอักษร "abcdef" ความแม่นยำระบุจำนวนหลักต่ำสุดที่จะปรากฏ; หากค่าที่ถูกแปลงสามารถแสดงเป็นตัวเลขที่น้อยลงก็จะถูกขยายด้วยศูนย์นำ ความแม่นยำเริ่มต้นคือ 1 ผลลัพธ์ของการแปลงศูนย์ด้วยความแม่นยำที่ชัดเจนของศูนย์จะต้องไม่มีอักขระ

สำหรับรายละเอียดเพิ่มเติมโปรดดูที่สเปค printf IEEE


ขึ้นอยู่กับสาเหตุดังกล่าวทำให้ผมคิดว่ามันจะดีกว่าที่จะมีการเปลี่ยนแปลง%02.2hhxไปหรือ%02x%.2x

สำหรับ Swift 5 วิธีการต่อไปนี้เป็นไปได้ทั้งหมด:

deviceToken.map({String(format: "%02x", $0)}).joined()
deviceToken.map({String(format: "%.2x", $0)}).joined()
deviceToken.reduce("", {$0 + String(format: "%02x", $1)})
deviceToken.reduce("", {$0 + String(format: "%.2x", $1)})

การทดสอบมีดังนี้:

let deviceToken = (0..<32).reduce(Data(), {$0 + [$1]})
print(deviceToken.reduce("", {$0 + String(format: "%.2x", $1)}))
// Print content:
// 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f

ขอบคุณสำหรับคำตอบนี้ ใช้งานกับ iOS 12 ได้หรือไม่ หรือมันขึ้นอยู่กับรุ่น Swift เท่านั้น?
Markus

1
@Markus ใช้งานได้ใน iOS 12 ขึ้นอยู่กับรุ่น Swift เท่านั้น
jqgsninimo

14

เป็นโซลูชันของฉันและทำงานได้ดีในแอปของฉัน:

    NSString* newToken = [[[NSString stringWithFormat:@"%@",deviceToken] 
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""];
  • แปลงNSDataเป็นNSStringด้วยstringWithFormat
  • ตัดแต่ง "<>"
  • ลบช่องว่าง

10
นี่เป็นการโทรโดยปริยาย-descriptionดังนั้นมันจึงไม่ปลอดภัยกว่าคำตอบที่ยอมรับ
jszumski

คุณช่วยลิงค์ที่มาของคุณหน่อยได้ไหม? ฉันไม่สามารถหาข้อมูลเกี่ยวกับมันได้ทุกที่ ขอบคุณ.
Zeb

พบมัน! ฉันคิดว่ามันแตกต่างกันเล็กน้อย ใช้แอตทริบิวต์ description โดยตรงไม่ปลอดภัยเพราะอาจมีการเปลี่ยนแปลงในรุ่นอนาคต แต่ถ้าคุณใช้ผ่านวิธี NSString คุณจะไม่ค่อยมีปัญหา
Zeb

5
ไม่มีสิ่งนี้เรียกdescriptionบนอุปกรณ์โทเค็นอย่าง jszumski พูด
Jonny

1
@ Zeb มันไม่ปลอดภัยที่จะเชื่อdescriptionว่าคุณเรียกมันโดยตรงหรือใช้มันด้วยวิธีอื่นเพราะรูปแบบของสตริงที่ส่งคืนสามารถเปลี่ยนแปลงได้ตลอดเวลา ทางออกที่ถูกต้องอยู่ที่นี่: stackoverflow.com/a/16411517/108105
Tom Dalling

10

ฉันคิดว่าการแปลงอุปกรณ์โตเค็นเป็นสตริงฐานสิบหกไม่มีความหมาย ทำไม? คุณจะส่งไปที่แบ็กเอนด์ของคุณที่มันจะถูกเปลี่ยนกลับเป็นไบต์เพื่อผลักดันให้ APNS ดังนั้นใช้เมธอดของNSDatabase64EncodedStringWithOptionsดันไปที่เซิร์ฟเวอร์จากนั้นใช้ reverse base64decoded data :) มันง่ายกว่ามาก :)

NSString *tokenString = [tokenData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];

@ jeet.chanchawat โปรดอย่าเพิ่มรหัสลงในคำตอบของผู้ใช้รายอื่น เราไม่ต้องการใส่คำเข้าไปในปากของพวกเขาโดยเฉพาะอย่างยิ่งเมื่อเพิ่ม Swift ในคำตอบ Objective-C เพิ่มคำตอบของคุณเองแทน
JAL

2
ฉันไม่อยากจะลอกเลียนคำตอบของ @Oleg Shanyuk เนื่องจากเป็นเพียงการแปลในภาษาอื่นที่สร้างขึ้นตามคำตอบของเขาดังนั้นเขาจึงสมควรได้รับการโหวตในอนาคต ถ้าฉันเพิ่มคำตอบอื่นมันจะให้ upvotes สำหรับคำตอบซึ่งเป็นการวิจัยของคนอื่น หวังว่านี่จะเป็นเหตุผลในการแก้ไข
jeet.chanchawat

10

ใน iOS 13 descriptionจะใช้งานไม่ได้

let deviceTokenString = deviceToken.map { String(format: "%02x", $0) }.joined()

เพื่อความชัดเจนลองแยกส่วนนี้ออกและอธิบายแต่ละส่วน:

วิธีการทำแผนที่ในแต่ละองค์ประกอบของลำดับ เนื่องจาก Data เป็นลำดับไบต์ใน Swift การปิดการส่งผ่านจะถูกประเมินสำหรับแต่ละไบต์ใน deviceToken String (format :) initializer ประเมินแต่ละไบต์ในข้อมูล (แสดงโดยพารามิเตอร์ที่ไม่ระบุชื่อ $ 0) โดยใช้ตัวระบุรูปแบบ% 02x เพื่อสร้างการแสดงเลขฐานสิบหกแบบไม่มีเลขศูนย์ 2 หลักของจำนวนเต็มจำนวนไบต์ / 8 บิต หลังจากรวบรวมแต่ละการแทนค่าไบต์ที่สร้างขึ้นโดยวิธีการแผนที่เข้าร่วม () เชื่อมแต่ละองค์ประกอบลงในสตริงเดียว

PS ไม่ใช้คำอธิบายให้สตริงที่แตกต่างใน iOS 12 และ iOS 13 และไม่ปลอดภัยตามขอบเขตในอนาคต นักพัฒนาไม่ควรพึ่งพารูปแบบเฉพาะสำหรับคำอธิบายของวัตถุ

// iOS 12
(deviceToken as NSData).description // "<965b251c 6cb1926d e3cb366f dfb16ddd e6b9086a 8a3cac9e 5f857679 376eab7C>"

// iOS 13
(deviceToken as NSData).description // "{length = 32, bytes = 0x965b251c 6cb1926d e3cb366f dfb16ddd ... 5f857679 376eab7c }"

สำหรับข้อมูลเพิ่มเติมอ่านนี้


10

ใน iOS 13 คำอธิบายจะอยู่ในรูปแบบที่แตกต่างกัน กรุณาใช้รหัสด้านล่างเพื่อดึงโทเค็นของอุปกรณ์

- (NSString *)fetchDeviceToken:(NSData *)deviceToken {
    NSUInteger len = deviceToken.length;
    if (len == 0) {
        return nil;
    }
    const unsigned char *buffer = deviceToken.bytes;
    NSMutableString *hexString  = [NSMutableString stringWithCapacity:(len * 2)];
    for (int i = 0; i < len; ++i) {
        [hexString appendFormat:@"%02x", buffer[i]];
    }
    return [hexString copy];
}

โซลูชั่นที่สมบูรณ์แบบสำหรับ iOS 13 ขอบคุณ Vishnu
Manish

1
มันไม่ได้รวบรวมในขณะนี้ - ในการห่วงควรจะเปลี่ยนเป็นlength lenเห็นได้ชัดว่าเป็นการเปลี่ยนแปลงเล็ก ๆ น้อย ๆ สำหรับฉันที่จะแก้ไข .. แต่ก็ใช้งานได้อย่างสมบูรณ์แบบ!
Anders Friis

คุณเป็นผู้ช่วยชีวิต
Moeez Akram

3

นี่เป็นวิธีที่สั้นกว่าเล็กน้อย:

NSData *token = // ...
const uint64_t *tokenBytes = token.bytes;
NSString *hex = [NSString stringWithFormat:@"%016llx%016llx%016llx%016llx",
                 ntohll(tokenBytes[0]), ntohll(tokenBytes[1]),
                 ntohll(tokenBytes[2]), ntohll(tokenBytes[3])];

3

ฟังก์ชั่นเวอร์ชั่น Swift

หนึ่งในสายการบิน:

let hexString = UnsafeBufferPointer<UInt8>(start: UnsafePointer(data.bytes),
count: data.length).map { String(format: "%02x", $0) }.joinWithSeparator("")

นี่คือรูปแบบการขยายเอกสารที่สามารถใช้ซ้ำได้

extension NSData {
    func base16EncodedString(uppercase uppercase: Bool = false) -> String {
        let buffer = UnsafeBufferPointer<UInt8>(start: UnsafePointer(self.bytes),
                                                count: self.length)
        let hexFormat = uppercase ? "X" : "x"
        let formatString = "%02\(hexFormat)"
        let bytesAsHexStrings = buffer.map {
            String(format: formatString, $0)
        }
        return bytesAsHexStrings.joinWithSeparator("")
    }
}

อีกทางเลือกหนึ่งให้ใช้reduce("", combine: +)แทนjoinWithSeparator("")การถูกมองว่าเป็นผู้เชี่ยวชาญการทำงานโดยเพื่อนของคุณ


แก้ไข: ฉันเปลี่ยน String ($ 0, radix: 16) เป็น String (รูปแบบ: "% 02x", $ 0) เนื่องจากต้องมีตัวเลขหนึ่งตัวเพื่อให้มีศูนย์เป็นศูนย์

(ฉันยังไม่รู้วิธีการทำเครื่องหมายคำถามว่าซ้ำกับคำถามอื่นดังนั้นฉันเพิ่งโพสต์คำตอบของฉันอีกครั้ง)


ใช้งานได้สำหรับฉันขอบคุณ
Hasya

3

2020

โทเค็นเป็นข้อความ ...

let tat = deviceToken.map{ data in String(format: "%02.2hhx", data) }.joined()

หรือถ้าคุณต้องการ

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

(ผลลัพธ์เหมือนกัน)


2

ทิ้งคำตอบของฉันไว้บนกอง หลีกเลี่ยงการใช้การวิเคราะห์สตริง มันไม่ได้รับประกันโดยเอกสารที่ NSData.description จะทำงานในลักษณะนั้นเสมอ

การใช้งาน Swift 3:

extension Data {
    func hexString() -> String {
        var bytesPointer: UnsafeBufferPointer<UInt8> = UnsafeBufferPointer(start: nil, count: 0)
        self.withUnsafeBytes { (bytes) in
            bytesPointer = UnsafeBufferPointer<UInt8>(start: UnsafePointer(bytes), count:self.count)
        }
        let hexBytes = bytesPointer.map { return String(format: "%02hhx", $0) }
        return hexBytes.joined()
    }
}

1

ฉันพยายามทดสอบสองวิธีด้วยรูปแบบ"%02.2hhx"และ"%02x"

    var i :Int = 0
    var j: Int = 0
    let e: Int = Int(1e4)
    let time = NSDate.timeIntervalSinceReferenceDate
    while i < e {
        _ =  deviceToken.map { String(format: "%02x", $0) }.joined()
        i += 1
    }
    let time2 = NSDate.timeIntervalSinceReferenceDate
    let delta = time2-time
    print(delta)

    let time3 = NSDate.timeIntervalSinceReferenceDate
    while j < e {
        _ =  deviceToken.reduce("", {$0 + String(format: "%02x", $1)})
        j += 1
    }
    let time4 = NSDate.timeIntervalSinceReferenceDate
    let delta2 = time4-time3
    print(delta2)

และผลลัพธ์ก็คือความเร็วที่เร็วที่สุดคือ"%02x"เฉลี่ย 2.0 vs 2.6 สำหรับเวอร์ชั่นที่ลดลง:

deviceToken.reduce("", {$0 + String(format: "%02x", $1)})

1

ใช้updateAccumulatingResultมีประสิทธิภาพมากขึ้นกว่าวิธีการอื่น ๆ อีกมากมายพบได้ที่นี่เพื่อให้ที่นี่เป็นSwiftiestวิธีการของคุณ stringify Dataไบต์:

func application(_ application: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let token = deviceToken.reduce(into: "") { $0 += String(format: "%.2x", $1) }
    print(token)
}

อเล็กซ์จะไม่เป็น% 02.2hhx
Fattie

0

สำหรับ Swift:

var characterSet: NSCharacterSet = NSCharacterSet( charactersInString: "<>" )
    var deviceTokenString: String = ( deviceToken.description as NSString )
    .stringByTrimmingCharactersInSet( characterSet )
    .stringByReplacingOccurrencesOfString( " ", withString: "" ) as String

println( deviceTokenString )

0

วิธีแก้ปัญหาหนึ่งบรรทัด

วัตถุประสงค์ C

NSString *token = [[data.description componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet]invertedSet]]componentsJoinedByString:@""];

รวดเร็ว

let token = data.description.componentsSeparatedByCharactersInSet(NSCharacterSet.alphanumericCharacterSet().invertedSet).joinWithSeparator("")

2
นี่คือทางออกที่ง่ายและดีที่สุด ขอบคุณ
Emmy

0

นี่คือวิธีที่คุณทำใน Xamarin.iOS

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    var tokenStringBase64 = deviceToken.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
    //now you can store it for later use in local storage
}

-1
NSString *tokenString = [[newDeviceToken description] stringByReplacingOccurrencesOfString:@"[<> ]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [[newDeviceToken description] length])];

วิธีแก้ปัญหาที่ดี ณ วันนี้มันสามารถมีส่วนร่วมกับหนังสือรับรอง. token.description.replacingOccurrences (จาก: "[<>]", กับ: "", ตัวเลือก:. regular expression, ช่วง: ไม่มี)
Frank


-2
-(NSString *)deviceTokenWithData:(NSData *)data
{
    NSString *deviceToken = [[data description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
    return deviceToken;
}

-2

รวดเร็ว

    // make sure that we have token for the devie on the App
    func application(application: UIApplication
        , didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {

            var tokenStr = deviceToken.description
            tokenStr = tokenStr.stringByReplacingOccurrencesOfString("<", withString: "", options: [], range: nil)
            tokenStr = tokenStr.stringByReplacingOccurrencesOfString(">", withString: "", options: [], range: nil)
            tokenStr = tokenStr.stringByReplacingOccurrencesOfString(" ", withString: "", options: [], range: nil)



            print("my token is: \(tokenStr)")

    }

-2

ใช้หมวดหมู่ที่ยอดเยี่ยม!

//. ไฟล์ h

@interface NSData (DeviceToken)

- (NSString *)stringDeviceToken;

@end    

// .m ไฟล์

#import "NSData+DeviceToken.h"

@implementation NSData (DeviceToken)

- (NSString *)stringDeviceToken {
    const unsigned *deviceTokenBytes = [deviceToken bytes];
    NSString *deviceToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                     ntohl(deviceTokenBytes[0]), ntohl(deviceTokenBytes[1]), ntohl(deviceTokenBytes[2]),
                     ntohl(deviceTokenBytes[3]), ntohl(deviceTokenBytes[4]), ntohl(deviceTokenBytes[5]),
                     ntohl(deviceTokenBytes[6]), ntohl(deviceTokenBytes[7])];
    return deviceToken;
}

@end

// AppDelegate.m

#import "NSData+DeviceToken.h"

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSString *token = deviceToken.stringDeviceToken;
}

ทำงานได้ดี!


อย่าพึ่งพาการใช้ "คำอธิบาย" รูปแบบของรูปแบบอาจเปลี่ยนแปลงได้ในอนาคต มันมีวัตถุประสงค์เพื่อแสดงผลเท่านั้น
Michael Peterson

-3

สวิฟท์ 3:

หากมีผู้ใดกำลังมองหาวิธีรับโทเค็นอุปกรณ์ใน Swift 3 ใช้ตัวอย่างข้อมูลที่แก้ไขด้านล่าง

    let characterSet: CharacterSet = CharacterSet( charactersIn: "<>" )

    let deviceTokenString: String = (deviceToken.description as NSString)
        .trimmingCharacters(in: characterSet as CharacterSet)
        .replacingOccurrences(of: " ", with: "")
        .uppercased()

    print(deviceTokenString)

2
ฉันไม่แนะนำให้ใช้คำอธิบายเนื่องจากไม่รับประกันว่าจะยังคงเหมือนเดิม ดูคำตอบของฉันที่นี่: stackoverflow.com/questions/9372815/…
swift taylor

-4
var token: String = ""
for i in 0..<deviceToken.count {
    token += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
}

print(token)

1
การใช้คำอธิบายไม่ปลอดภัยเนื่องจากไม่รับประกันว่าจะให้ผลลัพธ์เดียวกันในอนาคต
Sahil Kapoor

-4

ทางออก @kulss โพสต์ที่นี่ในขณะที่ขาดความสง่างาม แต่มีความเรียบง่ายไม่ทำงานใน iOS 13 อีกต่อไปเนื่องจากdescriptionจะทำงานแตกต่างกันสำหรับ NSData คุณยังสามารถใช้งานdebugDescriptionได้

NSString * deviceTokenString = [[[[deviceToken debugDescription]
                     stringByReplacingOccurrencesOfString: @"<" withString: @""] 
                    stringByReplacingOccurrencesOfString: @">" withString: @""] 
                   stringByReplacingOccurrencesOfString: @" " withString: @""];

-7

ลองอันนี้เว้นแต่ว่าข้อมูลจะถูกยกเลิก

NSString* newStr = [[NSString alloc] initWithData:newDeviceToken encoding:NSUTF8StringEncoding];


ฉันลองอันนั้นมันใช้งานไม่ได้ ฉันได้ให้ความเห็นในโค้ดของฉัน
Sheehan Alam

@SheehanAlam ผู้ชายคนนี้ทำให้มันผ่าน ดูว่ามันแปลงเป็นสตริงอย่างไร stackoverflow.com/questions/4994302/…
อาเหม็ด Naveed

-9
NSString *tokenstring = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding];

สิ่งนี้จะทำงานเมื่อข้อมูลเป็นสตริงอย่างไรก็ตาม DeviceToken ไม่ใช่สตริง
Simon Epskamp
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.