iOS - 如何在 iOS 10 中集成推送通知?
Posted
技术标签:
【中文标题】iOS - 如何在 iOS 10 中集成推送通知?【英文标题】:iOS- How to integrate push notification in iOS 10? 【发布时间】:2016-09-01 09:19:33 【问题描述】:我在 ios 8,9 中使用了以下代码:
UIMutableUserNotificationAction *action1;
action1 = [[UIMutableUserNotificationAction alloc] init];
[action1 setActivationMode:UIUserNotificationActivationModeBackground];
[action1 setTitle:@"REJECT"];
[action1 setIdentifier:NotificationActionOneIdent];
[action1 setDestructive:NO];
[action1 setAuthenticationRequired:NO];
UIMutableUserNotificationAction *action2;
action2 = [[UIMutableUserNotificationAction alloc] init];
[action2 setActivationMode:UIUserNotificationActivationModeBackground];////UIUserNotificationActivationModeBackground
[action2 setTitle:@"ACCEPT"];
[action2 setIdentifier:NotificationActionTwoIdent];
[action2 setDestructive:NO];
[action2 setAuthenticationRequired:NO];
UIMutableUserNotificationCategory *actionCategory;
actionCategory = [[UIMutableUserNotificationCategory alloc] init];
[actionCategory setIdentifier:NotificationCategoryIdent];
[actionCategory setActions:@[action1, action2]
forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObject:actionCategory];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:
UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
委托方法处理:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
//Handle according to app state
并且 //处理动作
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler
//Handle action as well
如何在 iOS 10 中使用 UserNotifications 和 UserNotificationsUI 框架做同样的事情?我还需要支持 iOS 8 和 iOS 9 吗?
【问题讨论】:
【参考方案1】:类型转换
适用于 Swift3
-
样品见this
导入
UserNotifications
框架并在Appdelegate中添加UNUserNotificationCenterDelegate
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
// Override point for customization after application launch.
//create the notificationCenter
let center = UNUserNotificationCenter.current()
center.delegate = self
// set the type as sound or badge
center.requestAuthorization(options: [.sound,.alert,.badge, .providesAppNotificationSettings]) (granted, error) in
// Enable or disable features based on authorization
application.registerForRemoteNotifications()
return true
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]])
token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
print("Registration succeeded!")
print("Token: ", token)
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError)
print("Registration failed!")
使用此委托接收通知
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void)
print("Handle push from foreground")
// custom code to handle push while app is in the foreground
print("\(notification.request.content.userInfo)")
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
print("Handle push from background or closed")
// if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background
print("\(response.notification.request.content.userInfo)")
func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?)
let navController = self.window?.rootViewController as! UINavigationController
let notificationSettingsVC = NotificationSettingsViewController()
navController.pushViewController(notificationSettingsVC, animated: true)
有关更多信息,请参阅 Apple API Reference
目标 C
AppDelegate.h 有以下几行:
第一步
//Add Framework in your project "UserNotifications"
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
第二步
AppDelegate.m
// define macro
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
第三步
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
application.applicationIconBadgeNumber = 0;
if( SYSTEM_VERSION_LESS_THAN( @"10.0" ) )
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeprovidesAppNotificationSettings) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
//if( option != nil )
//
// NSLog( @"registerForPushWithOptions:" );
//
else
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
if( !error )
// required to get the app to do anything at all about push notifications
dispatch_async(dispatch_get_main_queue(), ^
[[UIApplication sharedApplication] registerForRemoteNotifications];
);
NSLog( @"Push registration success." );
else
NSLog( @"Push registration FAILED" );
NSLog( @"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription );
NSLog( @"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
];
return YES;
这将作为调用 registerForRemoteNotifications 的结果触发:
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
// custom stuff we do to register the device with our AWS middleman
然后,当用户点击通知时,会触发:
当应用程序处于前台或后台但未关闭时,这将在 iOS 10 中触发
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void
(^)(UIBackgroundFetchResult))completionHandler
// iOS 10 will handle notifications through other methods
if( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO( @"10.0" ) )
NSLog( @"iOS version >= 10. Let NotificationCenter handle this one." );
// set a member variable to tell the new delegate that this is background
return;
NSLog( @"HANDLE PUSH, didReceiveRemoteNotification: %@", userInfo );
// custom code to handle notification content
if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive )
NSLog( @"INACTIVE" );
completionHandler( UIBackgroundFetchResultNewData );
else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground )
NSLog( @"BACKGROUND" );
completionHandler( UIBackgroundFetchResultNewData );
else
NSLog( @"FOREGROUND" );
completionHandler( UIBackgroundFetchResultNewData );
或使用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result)
];
那么对于iOS 12,这两种方法:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
NSLog( @"Handle push from foreground" );
// custom code to handle push while app is in the foreground
NSLog(@"%@", notification.request.content.userInfo);
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler
NSLog( @"Handle push from background or closed" );
// if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background
NSLog(@"%@", response.notification.request.content.userInfo);
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
openSettingsForNotification:(UNNotification *)notification
Open notification settings screen in app
【讨论】:
对于将项目升级到 XCode 8 的用户,请确保在链接库中包含 UserNotifications.framework。 跟随案例,注意方法 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler never be called.. can你告诉我怎么了? @Stony - 你是否在功能中启用了后台模式 @Anbu.Karthik 是的,我启用了“远程通知”。我敢肯定 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler 可以在收到推送通知时调用。但我不知道该方法 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler 的用途,因为我从未见过它被调用。 if( options != nil ) NSLog( @"registerForPushWithOptions:" );什么是选项变量?我没有得到..【参考方案2】:1st) 在项目的常规设置中将 UserNotifications.framework 添加到 Linked Frameworks 和 Libraries p>
2nd) 像这样将这些行添加到您的 AppDelagte
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate () <UIApplicationDelegate,UNUserNotificationCenterDelegate>
3rd) 获得响应
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
NSLog( @"for handling push in foreground" );
// Your code
NSLog(@"%@", notification.request.content.userInfo); //for getting response payload data
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
NSLog( @"for handling push in background" );
// Your code
NSLog(@"%@", response.notification.request.content.userInfo); //for getting response payload data
【讨论】:
“notification.request.content.userInfo”中没有第一个参数 应该是:response.notification.request.content.userInfo @biloshkurskyi.ss 我更新了我的答案谢谢你指出来。以上是关于iOS - 如何在 iOS 10 中集成推送通知?的主要内容,如果未能解决你的问题,请参考以下文章