I\'ve a very strange problem, I implemented:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchComp
Code that works fetching remote notifications, enable te remote notifications capability in background modes and i have background fetch enabled too (i don't know if it is necessary) I use this code:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler{
DLog(@"899- didReceiveRemoteNotification userInfo: %@",userInfo);
NSDictionary *custom=userInfo[@"custom"];
if(custom){
NSInteger code = [custom[@"code"] integerValue];
NSInteger info = [custom[@"info"] integerValue];
NSDictionary *messageInfo = userInfo[@"aps"];
[[eInfoController singleton] remoteNotificationReceived:code info:info messageInfo:messageInfo appInBackground:[UIApplication sharedApplication].applicationState==UIApplicationStateBackground];
handler(UIBackgroundFetchResultNewData);
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
DLog(@"899- didReceiveRemoteNotification userInfo: %@",userInfo);
NSDictionary *custom=userInfo[@"custom"];
if(custom){
NSInteger code = [custom[@"code"] integerValue];
NSInteger info = [custom[@"info"] integerValue];
NSDictionary *messageInfo = userInfo[@"aps"];
[[eInfoController singleton] remoteNotificationReceived:code info:info messageInfo:messageInfo appInBackground:[UIApplication sharedApplication].applicationState==UIApplicationStateBackground];
}
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
//NSLog(@"My token is: %@", deviceToken);
const unsigned *tokenBytes = (const unsigned *)[deviceToken bytes];
NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
[[eInfoController singleton] setPushNotificationToken:hexToken];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(@"Failed to get token, error: %@", error);
}
Code that stores the notification when it background, the key for me was to start a background download task to allow me to download the information in order to store it and then when app becomes active method is triggered i check if there is a missing notification stored to show it.
-(void)remoteNotificationReceived:(NSInteger)code info:(NSInteger)info messageInfo:(NSDictionary*)messageInfo appInBackground:(BOOL)appInBackground{
DLog(@"Notification received appInBackground: %d,pushCode: %ld, messageInfo: %@",appInBackground, (long)code,messageInfo);
switch (code){
case 0:
break;
case 1:
{
NSArray *pendingAdNotifiacations=[[NSUserDefaults standardUserDefaults] objectForKey:@"pendingAdNotifiacations"];
NSMutableDictionary *addDictionary=[[NSMutableDictionary alloc] initWithDictionary:messageInfo copyItems:YES];
[addDictionary setObject:[NSNumber numberWithInteger:info] forKey:@"ad_id"];
if(!pendingAdNotifiacations){
pendingAdNotifiacations=[NSArray arrayWithObject:addDictionary];
}else{
pendingAdNotifiacations=[pendingAdNotifiacations arrayByAddingObject:addDictionary];
}
[addDictionary release];
[[NSUserDefaults standardUserDefaults] setObject:pendingAdNotifiacations forKey:@"pendingAdNotifiacations"];
[[NSUserDefaults standardUserDefaults] synchronize];
DLog(@"pendingAdNotifiacations received: %@.",pendingAdNotifiacations);
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:(pendingAdNotifiacations)?[pendingAdNotifiacations count]:0];
DLog(@"783- pendingAdNotifiacations: %lu.",(unsigned long)((pendingAdNotifiacations)?[pendingAdNotifiacations count]:0));
if(appInBackground){
[AdManager requestAndStoreAd:info];
}else{
[AdManager requestAndShowAd:info];
}
}
break;
default:
break;
}
}
This is the relevant code to download the info in the background using a background task:
-(void)requestAdinBackgroundMode:(NSInteger)adId{
DLog(@"744- requestAdinBackgroundMode begin");
if(_backgroundTask==UIBackgroundTaskInvalid){
DLog(@"744- requestAdinBackgroundMode begin dispatcher");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
DLog(@"744- passed dispatcher");
[self beginBackgroundUpdateTask];
NSURL *requestURL=[self requestURL:adId];
if(requestURL){
NSURLRequest *request = [NSURLRequest requestWithURL:requestURL];
NSURLResponse * response = nil;
NSError * error = nil;
DLog(@"744- NSURLConnection url: %@",requestURL);
NSData * responseData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];
if(NSClassFromString(@"NSJSONSerialization"))
{
NSError *error = nil;
id responseObject = [NSJSONSerialization
JSONObjectWithData:responseData
options:0
error:&error];
if(error) {
NSLog(@"JSON reading error: %@.",[error localizedDescription]);
/* JSON was malformed, act appropriately here */ }
else{
if(responseObject && [responseObject isKindOfClass:[NSDictionary class]]){
if(responseObject && [[responseObject objectForKey:@"success"] integerValue]==1){
NSMutableDictionary *adDictionary=[[[NSMutableDictionary alloc] initWithDictionary:[responseObject objectForKey:@"ad"]] autorelease];
DLog(@"744- NSURLConnection everythig ok store: %@",adDictionary);
[self storeAd: adDictionary];
}
}
}
}
}
// Do something with the result
[self endBackgroundUpdateTask];
});
}
}
- (void) beginBackgroundUpdateTask
{
DLog(@"744- requestAdinBackgroundMode begin");
_backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUpdateTask];
}];
}
- (void) endBackgroundUpdateTask
{
DLog(@"744- End background task");
[[UIApplication sharedApplication] endBackgroundTask: _backgroundTask];
_backgroundTask = UIBackgroundTaskInvalid;
}
Well this is all I think, I post it because someone asked me to post an update, I hope it may help someone...