Sea*_*lly 5 objective-c apple-push-notifications ios ios8
我在iOS 8上的推送通知中添加了两个操作按钮:一个Accept按钮和一个Deny按钮.这两个按钮都不会打开应用程序,但根据按下的按钮,将会发出不同的服务器请求.这是我的设置:
+ (void)requestForPushNotificationToken {
UIApplication *application = [UIApplication sharedApplication];
// if ios 8 or greater
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
UIMutableUserNotificationAction *acceptAction = [[UIMutableUserNotificationAction alloc] init];
[acceptAction setActivationMode:UIUserNotificationActivationModeBackground];
[acceptAction setTitle:@"Accept"];
[acceptAction setIdentifier:@"ACCEPT_ACTION"];
[acceptAction setDestructive:NO];
[acceptAction setAuthenticationRequired:NO];
UIMutableUserNotificationAction *denyAction = [[UIMutableUserNotificationAction alloc] init];
[denyAction setActivationMode:UIUserNotificationActivationModeBackground];
[denyAction setTitle:@"Deny"];
[denyAction setIdentifier:@"DENY_ACTION"];
[denyAction setDestructive:NO];
[denyAction setAuthenticationRequired:NO];
UIMutableUserNotificationCategory *actionCategory = [[UIMutableUserNotificationCategory alloc] init];
[actionCategory setIdentifier:@"ACTIONABLE"];
[actionCategory setActions:@[acceptAction, denyAction]
forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObject:actionCategory];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert) categories:categories];
[application registerUserNotificationSettings:settings];
} else if ([application respondsToSelector:@selector(registerForRemoteNotificationTypes:)]) { // ios 7 or lesser
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在我的委托方法中,我指定当用户按下其中一个操作按钮时要采取的操作:
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:@"ACCEPT_ACTION"]) {
// Sending a request to the server here
}
else if ([identifier isEqualToString:@"DENY_ACTION"]) {
// Sending a request to the server here
}
if (completionHandler) {
completionHandler();
}
}
Run Code Online (Sandbox Code Playgroud)
理想的情况是用户不需要在整个过程中启动应用程序; 按Accept或Deny将对服务器进行不同的调用.使用上面的代码,我看到按钮操作的行为非常不稳定:
有谁能帮我弄清楚导致这种不稳定行为的原因是什么?提前致谢.
Sea*_*lly 12
我终于找到了原因.事实上,它有时是有效的,有时是不行的,应该更快地给我提示.
根据Apple的文档application:handleActionWithIdentifier:forRemoteNotification:completionHandler::
您对此方法的实现应执行与指定标识符关联的操作,并在完成后立即在completionHandler参数中执行该块.在实施结束时未能执行完成处理程序块将导致您的应用程序被终止.
我在application:handleActionWithIdentifier:forRemoteNotification:completionHandler方法结束时调用完成处理程序.但是,我在处理程序代码中向服务器发送请求的事实意味着我end of implementation不仅仅是在方法的最后; 我真正的目的在于回应我的要求.我编写它的方式,完成处理程序和回调是在两个不同的线程上,当完成处理程序在它到达回调之前运行时,它将失败.
因此,解决方案是将完成处理程序移动到请求的回调方法,即真正的"实现结束".像这样的东西:
[MyClient sendRequest:userInfo withSuccessBlock:^(id responseObject){
NSLog(@"Accept - Success");
if (completionHandler) {
completionHandler();
}
} withFailureBlock:^(NSError *error, NSString *responseString) {
NSLog(@"Accept - Failure: %@",[error description]);
if (completionHandler) {
completionHandler();
}
}];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5565 次 |
| 最近记录: |