iOS 13에서 푸시토큰이 iOS 13 이하 버전에서와 다르게 확인되는 경우가 있어서 해결 방법을 공유한다.

Problem

기존 iOS의 푸시토큰을 확인할 때 아래와 같이 인터넷에서 공유된 잘못된 방법을 많이 사용했었다.

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

iOS 13 이전 버전까지는 보통 아래와 같은 형식으로 반환되어 <, > 그리고 공백을 제거해서 사용했지만 적절한 방법이라고 할 수 없다.

<12345678 asdfghjk 45678900 dfb16ddd 12345678 45678900 45678900 asdfghjk>

iOS 13부터는 description를 사용할 경우 푸시토큰이 아래와 같이 반환되는경우가 있어서 문제가 될 수 있다. 심지어 bytes부분은 중간에 생략되기까지하여 서버에 저장할 경우 클라이언트 수정 없이 이 데이터만을 이용해서 문제를 해결하기도 힘들다.

{length=32,bytes=0x16406f0b18032ca902ed1117edd3bf6b...6221947229b7ca18}

Solution

이것은 apple의 갑작스러운 변경이 원인이라기 보다는 푸시 토큰을 가져오는 방법을 잘못 사용하고 있는것이 문제의 원인으로 아래와 같이 변경해야 한다.

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

이상한점은 iOS 13이라고 항상 발생하는 것은 아니고 아래와 같은 조합의 경우 발생했음을 참고로 공유한다.

CFNetwork/1098.4 Darwin/19.0.0
CFNetwork/1098.7 Darwin/19.0.0
CFNetwork/1107.1 Darwin/19.0.0
CFNetwork/1115 Darwin/19.0.0

iOS 13인 아래의 경우는 발생하지 않았다.

CFNetwork/1120 Darwin/19.0.0