So my friend got this email from OneSignal
Due to a change that may occur as part of the upcoming iOS 13 release, you must update to the latest versio
You can have look in the below code as I was also stuck on this problem. Here is the code by which you can get the device token in below iOS 13 and above.
NSString *str = [NSString stringWithFormat:@"%@", devTokendata]; // devTokendata is NSData
str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
str = [str stringByReplacingOccurrencesOfString:@"<" withString:@""];
str = [str stringByReplacingOccurrencesOfString:@">" withString:@""];
if (@available(iOS 13, *)) {
str = [self hexadecimalStringFromData:devToken];
NSLog(@"APNS Token: %@",str);
}
-(NSString *)deviceTokenFromData:(NSData *)data
{
NSUInteger dataLength = data.length;
if (dataLength == 0) {
return nil;
}
const unsigned char *dataBuffer = (const unsigned char *)data.bytes;
NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
for (int i = 0; i < dataLength; ++i) {
[hexString appendFormat:@"%02x", dataBuffer[i]];
}
return [hexString copy];
}
The way you do it is fine and it should continue to work on iOS 13. But some developers do it like this. To convert Data
into base-16 strings, they call description
, which returns something like
<124686a5 556a72ca d808f572 00c323b9 3eff9285 92445590 3225757d b83997ba>
And then they trim <
and >
and remove spaces.
On iOS 13 the description
called on token data returns something like
{ length = 32, bytes = 0xd3d997af 967d1f43 b405374a 13394d2f ... 28f10282 14af515f }
Which obviously makes this way broken.
Another example of wrong implementation (already edited to include correct implementation as well).
Some more examples might be found in this thread.
The same code for Swift 5 but bit shorter variant. Verified at iOS 13.
func getStringFrom(token:NSData) -> String {
return token.reduce("") { $0 + String(format: "%02.2hhx", $1) }
}
func getStringFrom(deviceToken: Data) -> String {
var token = ""
for i in 0..<deviceToken.count {
token += String(format: "%02.2hhx", arguments: [deviceToken[i]])
}
return token
}
Correctly capture iOS 13 Device Token in Xamarin.iOS
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
//DeviceToken = Regex.Replace(deviceToken.ToString(), "[^0-9a-zA-Z]+", "");
//Replace the above line whick worked up to iOS12 with the code below:
byte[] bytes = deviceToken.ToArray<byte>();
string[] hexArray = bytes.Select(b => b.ToString("x2")).ToArray();
DeviceToken = string.Join(string.Empty, hexArray);
}
Here is what's going on here:
Reference: https://dev.to/codeprototype/correctly-capture-ios-13-device-token-in-xamarin-1968
Solution 2: This also works fine
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
byte[] result = new byte[deviceToken.Length];
Marshal.Copy(deviceToken.Bytes, result, 0, (int)deviceToken.Length);
var token = BitConverter.ToString(result).Replace("-", "");
}
use deviceToken.debugDescription