iOS
NSData
NSString
device token
Swift programming

How can I convert my device token NSData into an NSString?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When Apple Push Notification service registers an iOS app, it gives your app a device token as binary data. In older Objective-C code that token often arrives as NSData, and many apps need to turn it into a hexadecimal string before sending it to a backend.

The important detail is that a device token is not text. It is raw bytes, so the correct conversion is a byte-by-byte hex encoding, not an arbitrary UTF-8 or string cast.

Why Hex Encoding Is the Right Conversion

APNs device tokens are opaque values. Apple does not promise that they are meaningful text, so converting them by assuming a text encoding will either fail or produce garbage.

The usual representation is a lowercase or uppercase hexadecimal string where each byte becomes two hex characters. That format is easy to log, store, and send to a server.

For example, a byte sequence containing four bytes becomes an eight-character hex string.

Objective-C Conversion Example

Here is a standard Objective-C helper:

objective-c
1- (NSString *)deviceTokenStringFromData:(NSData *)deviceToken {
2    const unsigned char *bytes = (const unsigned char *)deviceToken.bytes;
3    NSMutableString *hex = [NSMutableString stringWithCapacity:deviceToken.length * 2];
4
5    for (NSUInteger i = 0; i < deviceToken.length; i++) {
6        [hex appendFormat:@"%02x", bytes[i]];
7    }
8
9    return [hex copy];
10}

This code does three simple things:

  • Reads the bytes from the NSData object.
  • Formats each byte as a two-character hexadecimal value.
  • Appends the pieces into one final NSString.

That gives you a stable text representation suitable for network requests or logging.

Using It in the APNs Registration Callback

In older Objective-C app delegate code, the token usually arrives here:

objective-c
1- (void)application:(UIApplication *)application
2didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
3    NSString *tokenString = [self deviceTokenStringFromData:deviceToken];
4    NSLog(@"APNs token: %@", tokenString);
5}

At that point, the string can be sent to your server. The server can then associate that token with the logged-in user or device record.

The Old description Trick and Why to Avoid It

Older code samples on the internet often do something like this:

objective-c
NSString *token = [[deviceToken description]
    stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];

That worked in many older projects because NSData descriptions happened to show bytes in a readable form. The problem is that description is for debugging, not for a stable serialization contract. The explicit byte-to-hex loop is clearer and safer.

Modern Swift Equivalent

Even if your article title mentions NSData and NSString, it helps to know the modern Swift form because current iOS APIs use Data.

swift
1import Foundation
2
3func deviceTokenString(from data: Data) -> String {
4    data.map { String(format: "%02x", $0) }.joined()
5}

And in the callback:

swift
1func application(
2    _ application: UIApplication,
3    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
4) {
5    let token = deviceTokenString(from: deviceToken)
6    print(token)
7}

The concept is identical. Only the language and API types changed.

When You Might Not Need a String

If your backend and client are tightly controlled, you may choose to send the raw bytes in another serialized form. Still, most mobile systems and admin tools prefer the token as hex because it is easy to inspect and compare.

So the practical answer remains: convert the bytes to hex when you need a textual representation, and do not pretend the token is ordinary human-readable text.

Common Pitfalls

The biggest mistake is trying to create an NSString using a text encoding such as UTF-8. A device token is binary data, not a string payload.

Another common issue is relying on [deviceToken description] and string cleanup. It may appear to work, but it is less explicit and more fragile than direct byte formatting.

Be careful with uppercase versus lowercase hex too. APNs itself does not care about the visual case of the string, but your backend should normalize one format consistently.

Finally, remember that device tokens can change. Converting them correctly is only part of the job. You should also update the stored token whenever APNs gives you a new one.

Summary

  • An APNs device token in NSData is binary data, not text.
  • The correct conversion to NSString is a byte-by-byte hexadecimal encoding.
  • Use an explicit loop over deviceToken.bytes in Objective-C.
  • Avoid relying on NSData description output for production serialization.
  • Send the normalized hex string to your backend and be prepared for token rotation over time.

Course illustration
Course illustration

All Rights Reserved.