Reputation: 1823
How to get the device token from new xCode 8, Swift 3 in iOS 10?
Here is the code to register notification:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
DispatchQueue.main.async {
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
}
return true
}
func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
if notificationSettings.types != UIUserNotificationType() {
application.registerForRemoteNotifications()
}
}
Here i get the token, but i get the following error
Cannot invoke initializer for type 'UnsafePointer<CChar>' with an argument list of type '(UnsafeRawPointer)':
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let chars = UnsafePointer<CChar>((deviceToken as NSData).bytes)
var token = ""
for i in 0..<deviceToken.count {
token += String(format: "%02.2hhx", arguments: [chars[i]])
}
print("Registration succeeded!")
print("Token: ", token)
}
Can anyone help me solve it?
Upvotes: 20
Views: 29237
Reputation: 120022
Since you may need this token in different methods (like firebase, web engage, branch, etc), you can use a custom class to initial an APNS from the data containing both data
and string
public class APNS {
public init(deviceToken data: Data) {
self.data = data
self.string = data.map { data in String(format: "%02.2hhx", data) } .joined()
}
public let data: Data
public let string: String
}
then you can use it anywhere you need:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = APNS(deviceToken: deviceToken)
print(token.string)
}
Upvotes: 0
Reputation: 14073
One line:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let apnsDeviceToken = deviceToken.map {String(format: "%02.2hhx", $0)}.joined()
}
Or a modular/encapsulated/OOP way:
extension Data {
var string: String {
return map {String(format: "%02.2hhx", $0)}.joined()
}
}
Then you can do this:
let token = deviceToken.string
Upvotes: 6
Reputation: 4182
Code from Mixpanel library
let tokenChars = (deviceToken as NSData).bytes.assumingMemoryBound(to: CChar.self)
var tokenString = ""
for i in 0..<deviceToken.count {
tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
Upvotes: 0
Reputation: 3924
Working Code for getting push notification token - iOS 11 or greater, Swift 4
Request user permission
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert,UIUserNotificationType.badge, UIUserNotificationType.sound]
let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
return true
}
Getting device token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
print(token)
}
In case of error
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("i am not available in simulator \(error)")
}
Upvotes: 1
Reputation: 3016
This method may solve your problem in iOS 10 and greater:
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)
}
Upvotes: 38
Reputation: 1
It could work:
let chars = UnsafePointer<CChar>((deviceToken as NSData).bytes.assumingMemoryBound(to:CChar.self))
Thanks!
Upvotes: 0
Reputation: 1823
The below snnipet is working with Eric Aya solution :
let token = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
Thanks for all help :)
Upvotes: 3
Reputation: 11629
Swift 3 example taken from raywenderlich.com.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
let tokenParts = deviceToken.map { data -> String in
return String(format: "%02.2hhx", data)
}
let token = tokenParts.joined()
print(token)
}
Upvotes: 6
Reputation: 56
Faced the same problem, this is the only thing that helped me:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = String(format: "%@", deviceToken as CVarArg)
.trimmingCharacters(in: CharacterSet(charactersIn: "<>"))
.replacingOccurrences(of: " ", with: "")
}
Upvotes: 3
Reputation: 295
var pushToken = String(format: "%@", deviceToken as CVarArg)
pushToken = pushToken.trimmingCharacters(in: CharacterSet(charactersIn: "<>"))
pushToken = pushToken.replacingOccurrences(of: " ", with: "")
Upvotes: 12