【发布时间】:2013-12-23 10:31:20
【问题描述】:
我有一个很奇怪的问题,我实现了:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
用于静默远程推送通知。
当应用程序在后台并连接到 Xcode 时,它可以完美运行。
当我拔下任何 iOS 设备并运行应用程序时,转到后台并发送远程通知,didReceiveRemoteNotification:fetchCompletionHandler 不会被调用。
我的代码如下:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSInteger pushCode = [userInfo[@"pushCode"] integerValue];
NSLog(@"Silent Push Code Notification: %i", pushCode);
NSDictionary *aps = userInfo[@"aps"];
NSString *alertMessage = aps[@"alert"];
if (pushCode == kPushCodeShowText) {
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [NSDate date];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = alertMessage;
localNotif.alertAction = @"OK";
localNotif.soundName = @"sonar.aiff";
// localNotif.applicationIconBadgeNumber = 0;
localNotif.userInfo = nil;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotif];
UILocalNotification *clearNotification = [[UILocalNotification alloc] init];
clearNotification.fireDate = [NSDate date];
clearNotification.timeZone = [NSTimeZone defaultTimeZone];
clearNotification.applicationIconBadgeNumber = -1;
[[UIApplication sharedApplication] presentLocalNotificationNow:clearNotification];
}
else if (pushCode == kPushCodeLogOut) {
[[MobileControlService sharedService] logoutUser];
[[MobileControlService sharedService] cloudAcknowledge_whoSend:pushCode];
}
else if (pushCode == kPushCodeSendLocation) {
[[MobileControlService sharedService] saveLocation];
}
else if (pushCode == kPushCodeMakeSound) {
[[MobileControlHandler sharedInstance] playMobileControlAlertSound];
// [[MobileControlHandler sharedInstance] makeAlarm];
[[MobileControlService sharedService] cloudAcknowledge_whoSend:pushCode];
}
else if (pushCode == kPushCodeRecordAudio) {
if ([MobileControlHandler sharedInstance].isRecordingNow) {
[[MobileControlHandler sharedInstance] stopRecord];
} else {
[[MobileControlHandler sharedInstance] startRecord];
}
[[MobileControlService sharedService] cloudAcknowledge_whoSend:pushCode];
}
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)saveLocation {
bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];
char *hostname;
struct hostent *hostinfo;
hostname = "http://m.google.com";
hostinfo = gethostbyname(hostname);
if (hostname == NULL) {
NSLog(@"No internet connection (saveLocation)");
return;
}
if (self.locationManager.location.coordinate.latitude == 0.0 || self.locationManager.location.coordinate.longitude == 0.0) {
NSLog(@"saveLocation - coordinates are 0.0.");
return;
}
NSLog(@"saveLocation - trying to get location.");
NSString *postBody = [NSString stringWithFormat:@"Lat=%@&Lon=%@&Date=%@&userID=%@&batteryLevel=%@&version=%@&accuracy=%@&address=%@", self.myInfo.lat, self.myInfo.lon, self.myInfo.date, self.myInfo.userID, self.myInfo.batteryLevel, self.myInfo.version, self.myInfo.accuracy, self.myInfo.address];
NSURL *completeURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/saveLocation", WEB_SERVICES_URL]];
NSData *body = [postBody dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:completeURL];
[request setHTTPMethod:@"POST"];
[request setValue:kAPP_PASSWORD_VALUE forHTTPHeaderField:kAPP_PASSWORD_KEY];
[request setHTTPBody:body];
[request setValue:[NSString stringWithFormat:@"%d", body.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
if (__iOS_7_And_Heigher) {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"saveLocation Error: %@", error.localizedDescription);
} else {
NSString *responseXML = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"\n\nResponseXML(saveLocation):\n%@", responseXML);
[self cloudAcknowledge_whoSend:kPushCodeSendLocation];
}
}];
[dataTask resume];
}
else {
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
NSLog(@"saveLocation Error: %@", connectionError.localizedDescription);
} else {
NSString *responseXML = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"\n\nResponseXML(saveLocation):\n%@", responseXML);
[self cloudAcknowledge_whoSend:kPushCodeSendLocation];
}
}];
}
}
- (void)startBackgroundTask {
bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];
}
- (void)endBackgroundTask {
if (bgTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
而[self endBackgroundTask] 在cloudAcknowledge 函数的末尾。
知道这里到底发生了什么吗?
编辑:
有效载荷是这样的:
{ aps = { "content-available" = 1; }; pushCode = 12; }
【问题讨论】:
-
我前段时间正在研究这个问题,如果应用程序不活动(向上滑动),iOS 7 中的静默推送通知似乎会被忽略。这是开发人员与 Apple 支持人员交谈并得到答案的线程:devforums.apple.com/thread/209664?tstart=0 我仍然不确定在那之后如何继续。 ://
-
发送带有文本和声音的推送通知有效,但如果应用程序未连接到 xcode 并运行,则数据不会传递到应用程序。更糟糕的是,我什至在另一个项目中尝试过,我也遇到了同样的问题。
-
在 devforums 中发现的一条较新的评论说 iOS 7.1 beta 3 解决了这个问题。 devforums.apple.com/thread/210498?tstart=0 所以在 2014 年 3 月之后(或者 iOS 7.1 发布时)一切都会好起来的... -_-
-
你们中的任何人都测试过它是否适用于生产配置文件?
-
连接到 Xcode 时没问题。我的应用程序在后台和生产中不会触发委托方法。有解决办法吗?
标签: ios objective-c debugging background apple-push-notifications