I have created 2 sample (single view) projects to test push notifications, I didn't add any code except for the notifications setup code as following:
Project1 (Swift 2):
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
print("didRegisterUserNotificationSettings got called")
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let trimmedDeviceToken = deviceToken.description .stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
.stringByReplacingOccurrencesOfString(" ", withString: "")
print("Device Token \(trimmedDeviceToken)")
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print("Failed to get token, error: \(error)")
}
Project2 (Objective-C):
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationSettings* notificationSettings =
[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert|UIUserNotificationTypeBadge) categories:nil];
[application registerUserNotificationSettings:notificationSettings];
[application registerForRemoteNotifications];
return YES;
}
-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
NSLog(@"didRegisterUserNotificationSettings got called");
}
-(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString* newToken = [deviceToken description];
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"Device Token %@", newToken);
}
-(void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(@"Failed to get token, error: %@", error);
}
the objective-c project works fine on all tested devices: registers itself for remote notifications and receives a device token in the delegate callback method, but the swift project couldn’t get any of the delegate callbacks.
read what I’ve tried before marking this question as duplicate:
1) AppID is push notification enabled
2) Push certificate type is production and Provisioning profile is AdHoc production
3) both projects use the same AppID, push certificate and provisioning profile
4) both projects have been tested on 3 different iPhones (5, 6 & 6Plus) all running iOS 9.2, deleted the app with every install and restarted all of them many times
5) built both projects with Xcode 7.2 on 2 different MAC Pro machines
6) all 3 iPhones use internet connection without a firewall and all ports are open (as stated in this technical note), also changed the internet connection on the 3 devices to be a 3G connection instead of a WIFI.
7) checked/unchecked Push Notifications in project settings -> capabilities for both projects (by the way, this point has no effect as i tested it)
8) tried Xcode Run (the top button) and Export ipa package for both projects
9) tried both (application) & ( [UIApplication sharedApplication] for objective-c and UIApplication.sharedApplication() ) for swift with the method registerForRemoteNotifications
10) tried another brand new AppID, push certificate and provisioning profile for both projects.
11) deleted both projects, and created another 2 new projects with the same code as above
the objective-c project after all these tries works fine and receives a device token through didRegisterForRemoteNotificationsWithDeviceToken method but the swift one does not work.
I have generated 3 APN log files from the iPhone 6Plus device using PersistentConnectionLogging.mobileconfig
profile by Apple, and uploaded them here, (inside apsd_2016_02_24_11_36_29+0300.log
file the objective-c project BundleID is XXXXX.push.notification
and the swift project BundleID is XXXXX.apnsswift
)
it turns out that the reason behind this weird problem is the swift's print
method which does not show the output in device's log in contrast to NSLog
, the swift app has no problem, it just need to use NSLog
to show the messages in Push Notification delegate callback methods.
//print("Device Token \(trimmedDeviceToken)")
NSLog("Device Token: %@",trimmedDeviceToken)
Are you 100% sure that application:didFinishLaunchingWithOptions:
is called at all in the Swift version? Could it be that you forgot to e.g. set the app delegate's name in the Swift version? To check, add some logging code to the Swift application:didFinishLaunchingWithOptions:
as well.
Also, make sure to add @objc
to the Swift app delegate class (if it isn't already) and try (this is a really long shot) adding the dynamic
keyword to the delegate methods.
And try replacing UIApplication.sharedApplication()
with application
(another long shot).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With