Push Notification Using Api - ios

I am working on push notifications,i have an api for push notifications but i don't no how to implement the code.i am using the ios 10 version,please help me.

You can get full idea about implementating Push notification in iOS 10 from below link. Here you will also find steps to implement the same in XCode 8. Please refer below link: Push notification issue with iOS 10

If we use IOS 10 we need to add new frame work and some code
STEP : 1
From iOS 10, we must add UserNotifications framework and delegat.First add this.
STEP : 2
Add the delegate UNUserNotificationCenterDelegate
Now appDelegate.h
#import <UserNotifications/UserNotifications.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
appDelegate.m
STEP : 3
- (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) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if( !error )
{
[[UIApplication sharedApplication] registerForRemoteNotifications]; // required to get the app to do anything at all about push notifications
NSLog( #"Push registration success." );
}
else
{
NSLog( #"Push registration FAILED" );
NSLog( #"ERROR: %# - %#", error.localizedFailureReason, error.localizedDescription );
NSLog( #"SUGGESTIONS: %# - %#", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
}
}];
}
return YES;
}
STEP : 4
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// custom stuff we do to register the device with our AWS middleman
NSString *strToken = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#"<>"]];
strToken = [strToken stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"content---%#", strToken);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",#"your url here"]]];
[request setHTTPMethod:#"POST"];
//Pass The String to server
NSString *userUpdate =[NSString stringWithFormat:#"device_token=%#",strToken,nil];
//Check The Value what we passed
NSLog(#"the data Details is =%#", userUpdate);
//Convert the String to Data
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[request setHTTPBody:data1];
//Create the response and Error
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if(httpResponse.statusCode == 200)
{
if(httpResponse.statusCode == 200)
{
NSError *parseError = nil;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
NSLog(#"The response is - %#",responseDictionary);
}
else
{
NSLog(#"Error");
}
}
else
{
NSLog(#"faield to connect");
}
}];
[dataTask resume];
}
STEP : 5
-(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 );
}
}
//OR
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
}];
NSLog(#"Received notification: %#", userInfo);
if ([userInfo count]!=0)
{
NSMutableArray *notify=[[NSMutableArray alloc]init];
NSMutableArray *mutableRetrievedDictionary;
mutableRetrievedDictionary = [[NSUserDefaults standardUserDefaults] objectForKey:#"noyificationcount"] ;
NSMutableArray *deviealert = [[NSUserDefaults standardUserDefaults] objectForKey:#"noyificationcount"] ;
deviealert=[[NSMutableArray alloc]init];
[notify addObject: [[userInfo valueForKey:#"aps"] valueForKey:#"alert"]];
NSLog(#"notification is - %#", notify);
NSString *strAlertValue = [[userInfo valueForKey:#"aps"] valueForKey:#"badge"];
NSLog(#"my message-- %#",strAlertValue);
deviealert=[notify mutableCopy];
NSLog(#"new...%#",deviealert);
[[ NSUserDefaults standardUserDefaults]setObject:deviealert forKey:#"noyificationcount" ];
[[NSUserDefaults standardUserDefaults]synchronize];
NSLog(#"dev.....%#",deviealert);
[UIApplication sharedApplication].applicationIconBadgeNumber+=1;
}
}
STEP : 6
For Foreground State
- (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);
}
STEP : 7
For Background State
- (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);
//Adding notification here
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadTheTable" object:nil];
}

Related

Rich push notification not working with FCM in IOS

I've added UNNotificationServiceExtension and UNNotificationContentExtension in my project for rich push notification. Please refer the code below which i've added for the same.
Code:
#import "NotificationService.h"
#interface NotificationService ()
#property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
#property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
#end
#implementation NotificationService {
NSURLSession *session;
}
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
NSDictionary *userInfo = request.content.userInfo;
if (userInfo == nil) {
[self contentComplete];
return;
}
if ([userInfo objectForKey:#"pic_url"]) {
[self loadAttachmentForUrlString:[userInfo objectForKey:#"pic_url"]
completionHandler: ^(UNNotificationAttachment *attachment) {
self.bestAttemptContent.attachments = [NSArray arrayWithObjects:attachment, nil];
}];
}
}
- (void)loadAttachmentForUrlString:(NSString *)urlString
completionHandler:(void (^)(UNNotificationAttachment *))completionHandler
{
__block UNNotificationAttachment *attachment = nil;
__block NSURL *attachmentURL = [NSURL URLWithString:urlString];
NSString *fileExt = [#"." stringByAppendingString:[urlString pathExtension]];
session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:attachmentURL
completionHandler: ^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) {
if (error != nil)
{
NSLog(#"%#", error.localizedDescription);
}
else
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localURL = [NSURL fileURLWithPath:[temporaryFileLocation.path
stringByAppendingString:fileExt]];
[fileManager moveItemAtURL:temporaryFileLocation
toURL:localURL
error:&error];
NSError *attachmentError = nil;
attachment = [UNNotificationAttachment attachmentWithIdentifier:[attachmentURL lastPathComponent]
URL:localURL
options:nil
error:&attachmentError];
if (attachmentError)
{
NSLog(#"%#", attachmentError.localizedDescription);
}
}
completionHandler(attachment);
}];
[task resume];
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
[self contentComplete];
}
- (void)contentComplete
{
[session invalidateAndCancel];
self.contentHandler(self.bestAttemptContent);
}
#end
I'm using the following payload
{
"to": "9yJUWBA",
"mutable_content": true,
"category": "myNotificationCategory",
"notification":
{
"title":"Realtime Custom Push Notifications",
"subtitle":"Now with iOS 10 support!",
"body":"Add multimedia content to your notifications"
}
}
The problem is i'm not getting the notification. I've used the following tutorial for implementing the rich push notification. I've checked different answers available but none of them worked for me. I've also tried to debug the didReceiveNotificationRequest method by attaching the extension process but the breakpoint not triggered.
https://mobisoftinfotech.com/resources/mguide/ios-10-rich-notifications-tutorial/
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
//Called when a notification is delivered to a foreground app.
NSLog(#"Userinfo willPresentNotification%#",notification.request.content.userInfo);
// Print message ID.
/*
NSDictionary *userInfo = notification.request.content.userInfo;
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
*/
completionHandler(UNNotificationPresentationOptionAlert);
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
//Called to let your app know which action was selected by the user for a given notification.
NSLog(#"Userinfo didReceiveNotificationResponse%#",response.notification.request.content.userInfo);
// Print message ID.
/*
NSDictionary *userInfo = notification.request.content.userInfo;
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
*/
}
Use above methods and these method available iOS 10 and onwards.
for debugging notification service extension please visit below link
Debug Notification Extensions
if you give support your application iOS 9 onwards then you have to put both methods below are for above iOS 10 and you also wrote in your question
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
/*
// Print message ID.
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
*/
// Print full message.
NSLog(#"Userinfo didReceiveRemoteNotification 1 %#",userInfo);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
/*
// Print message ID.
if (userInfo[kGCMMessageIDKey]) {
NSLog(#"Message ID: %#", userInfo[kGCMMessageIDKey]);
}
*/
// Print full message.
NSLog(#"Userinfo didReceiveRemoteNotification 2 %#",userInfo);
completionHandler(UIBackgroundFetchResultNewData);
}
let me know if you have query.
#interface NotificationService ()
#property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
#property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
#end
#implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler
{
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
// Modify the notification content here...
self.bestAttemptContent.title = #"";
self.bestAttemptContent.subtitle = #"";
// self.bestAttemptContent.body = [NSString stringWithFormat:#"%#", self.bestAttemptContent.body];
NSDictionary *dictPushNotiData = request.content.userInfo;
NSString *imageURL = #"";
NSString *videoURL = #"";
if(dictPushNotiData[#"xxx_details"])
{
NSString *jsonString = [dictPushNotiData objectForKey:#"xxx_details"];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
// If Instagram Notification Informations then call InstagramViewController
if(jsonData)
{
NSMutableDictionary *dictXXX = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
NSLog(#"dictXXX : %#",dictXXX);
//self.bestAttemptContent.title = [NSString stringWithFormat:#"%#", [dictXXX objectForKey:#"xxxx"]];
//self.bestAttemptContent.subtitle = [NSString stringWithFormat:#"%#", [dictXXX objectForKey:#"xxxx"]];
NSString *strBody = #"Notification xxxx x xxxx Post";
if([[dictXXX objectForKey:#"xxxx"] length] > 0)
{
strBody = [dictXXX objectForKey:#"xxxx"];
}
self.bestAttemptContent.body = [NSString stringWithFormat:#"%#",strBody];
imageURL = [dictXXX objectForKey:#"xxxx"];
videoURL = [dictXXX objectForKey:#"xxxx"];
}
}
NSString *strAttachment = nil;
// if (videoURL.length > 0)
// { //Prioritize videos over image
// strAttachment = videoURL;
// }
// else
if (imageURL.length > 0)
{
strAttachment = imageURL;
}
else
{
self.contentHandler(self.bestAttemptContent); //Nothing to add to the push, return early.
return;
}
// If there is an image in the payload, this part
// will handle the downloading and displaying of the image.
if (strAttachment) {
NSURL *URL = [NSURL URLWithString:strAttachment];
NSURLSession *LPSession = [NSURLSession sessionWithConfiguration:
[NSURLSessionConfiguration defaultSessionConfiguration]];
[[LPSession downloadTaskWithURL:URL completionHandler: ^(NSURL *temporaryLocation, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"Leanplum: Error with downloading rich push: %#",[error localizedDescription]);
self.contentHandler(self.bestAttemptContent);
return;
}
NSString *fileType = [self determineType:[response MIMEType]];
NSString *fileName = [[temporaryLocation.path lastPathComponent] stringByAppendingString:fileType];
NSString *temporaryDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
[[NSFileManager defaultManager] moveItemAtPath:temporaryLocation.path toPath:temporaryDirectory error:&error];
NSError *attachmentError = nil;
UNNotificationAttachment *attachment =
[UNNotificationAttachment attachmentWithIdentifier:#"" URL:[NSURL fileURLWithPath:temporaryDirectory] options:nil error:&attachmentError];
if (attachmentError != NULL) {
NSLog(#"Leanplum: Error with the rich push attachment: %#",
[attachmentError localizedDescription]);
self.contentHandler(self.bestAttemptContent);
return;
}
self.bestAttemptContent.attachments = #[attachment];
NSLog(#"self.bestAttemptContent.attachments : %#",
self.bestAttemptContent.attachments);
self.contentHandler(self.bestAttemptContent);
[[NSFileManager defaultManager] removeItemAtPath:temporaryDirectory error:&error];
}] resume];
}
}
- (NSString*)determineType:(NSString *) fileType {
// Determines the file type of the attachment to append to NSURL.
if ([fileType isEqualToString:#"image/jpeg"]){
return #".jpg";
}
if ([fileType isEqualToString:#"image/gif"]) {
return #".gif";
}
if ([fileType isEqualToString:#"image/png"]) {
return #".png";
} else {
return #".tmp";
}
}

iOS load UIWebView URL from notification

I'm having a strange issue, using Xcode 5 and testing on iOS 7, I'm sending an extra parameter with the apn request named "url", I need to open that URL in the webview when the notification is received, but the app freeze when the notification arrives if it was connected to the USB, or does nothing when is not connected.
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"Did Register for Remote Notifications with Device Token (%#)", deviceToken);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Did Fail to Register for Remote Notifications");
NSLog(#"%#, %#", error, error.localizedDescription);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Register for Remote Notifications
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
if (launchOptions != nil) {
// Launched from push notification
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSLog(#"Notification received");
[self application:application didReceiveRemoteNotification:(NSDictionary*)notification];
}
return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if (application.applicationState == UIApplicationStateActive) {
// app was already in the foreground
NSLog(#"app was already in the foreground");
} else {
// app was just brought from background to foreground
NSLog(#"app was just brought from background to foreground");
}
if ([userInfo objectForKey:#"url"])
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"loadNotificationUrl" object:self userInfo:userInfo];
}
}
And that's what is in the ViewerController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *urlString = #"http://example.com/?action=home";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[webView loadRequest:urlRequest];
webView.delegate = self;
webView.opaque = NO;
webView=[[UIWebView alloc]init];
[webView setBackgroundColor:[UIColor grayColor]];
[webView setDelegate:(id<UIWebViewDelegate>)self];
[self.view addSubview:webView];
activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.frame = CGRectMake(200.0, 200.0, 100.0, 40.0);
activityIndicator.center = self.view.center;
[self.view addSubview: activityIndicator];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(loadNotificationUrl:)
name:#"loadNotificationUrl" object:nil];
}
-(void)loadNotificationUrl:(NSNotification*) notification
{
NSDictionary* userInfo = notification.userInfo;
NSString* NotificationUrl = (NSString*)userInfo[#"url"];
NSLog (#"Successfully received: %#", NotificationUrl);
NSURL *url = [NSURL URLWithString:NotificationUrl];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[webView loadRequest:urlRequest];
}
As my little experience, this should load the URL when the notification is clicked, but it is either freeze or does nothing, can anybody tell me where is my mistake please?

Device token is not registered for ios 9

I implement the push notification for ios.But the device token is get for ipad ,ios v 8.3 but when i install the app in iphone 6s plus v9.0 then deveice token is not registerd.I create the all certificate according to this reference but i get the notification in ipad but not get iphone .
So what is the problem.I can not find out.Please help me
if(IS_OS_8_OR_LATER) {
//Right, that is the point
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
else{
//register to receive notifications
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[application registerForRemoteNotifications];
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token=[deviceToken description];
token=[token stringByReplacingOccurrencesOfString:#">" withString:#""];
token=[token stringByReplacingOccurrencesOfString:#"<" withString:#""];
token=[token stringByReplacingOccurrencesOfString:#" " withString:#""];
if (token != nil) {
[[NSUserDefaults standardUserDefaults] setObject:token forKey:#"DEVICE_TOKEN"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
NSLog(#"token-->%#",token);
}
-(void)registerDeviceToken
{
NSUserDefaults* errDefaults = [NSUserDefaults standardUserDefaults];
NSString *regerr = #"no valid 'aps-environment' entitlement string found for application";
if ([[errDefaults objectForKey:#"ErrDesc"] isEqual: regerr] || [errDefaults objectForKey:#"DEVICE_TOKEN"] == nil) {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Device token not register." message:#"Please check in member center that you have valid provisioning profile for your app." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
else{
NSUserDefaults* statusvalue = [NSUserDefaults standardUserDefaults];
NSString *status = [statusvalue objectForKey:#"status"];
NSLog(#"Status->%#",status);
if ([status isEqualToString: #"SUCCESS"])
{
NSLog(#"%#",#"No need to register!!!");
}
else
{
NSString *urlString=[NSString stringWithFormat:#"%#?email=&regid=%#&app_type=utnews_v1&mobile=%#",webAPIURL,[[NSUserDefaults standardUserDefaults] objectForKey:#"DEVICE_TOKEN"],[[NSUserDefaults standardUserDefaults] objectForKey:#"mobile_no"]];
NSURL *url=[NSURL URLWithString:urlString];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
NSLog(#"url-->%#",request.URL);
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if(error)
{
[[[UIAlertView alloc] initWithTitle:#"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil] show];
}
else if (data.length>0)
{
NSString *responseString=[[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
NSLog(#"Response string-->%#",responseString);
NSMutableDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSString *parsevalue = parsedObject[#"status"];
NSLog(#"%#",parsevalue);
NSUserDefaults* statusvalue = [NSUserDefaults standardUserDefaults];
// Store data in prefereances
[statusvalue setObject:parsevalue forKey:#"status"];
// Save to disk
[statusvalue synchronize];
// NSDictionary *jsonDict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
}
else
{
// [[[UIAlertView alloc] initWithTitle:#"Alert" message:#"No response from server.Please try again." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil] show];
}
}];
}
}
}
May be you should add [[UIApplication sharedApplication] registerForRemoteNotifications]; in if(IS_OS_8_OR_LATER) statement. Hope it help
Below code might be solved your problem from version iOS 6 and greater.
registerForRemoteNotificationTypes is Deprecated from `iOS 8.0.
#ifdef __IPHONE_8_0
if (IS_OS_EQUAL_GRETER_8) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
UIUserNotificationSettings *notificationSetting=[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound| UIRemoteNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSetting];
}else{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound| UIRemoteNotificationTypeBadge)];
}
#else
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound| UIRemoteNotificationTypeBadge)];
#endif

WatchKit return reply() inside a block in handleWatchKitExtensionRequest:

I saw this SO post where apparently data was being fetched and returned to the Watch extension like so:
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply
{
if ( [[userInfo objectForKey:#"request"] isEqualToString:#"getData"] )
{
// get data
// ...
reply( data );
}
}
But when I try to call 'reply()' inside a block after getting network data like so:
__block UIBackgroundTaskIdentifier watchKitHandler;
watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:#"backgroundTask"
expirationHandler:^{
watchKitHandler = UIBackgroundTaskInvalid;
}];
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply
{
NSMutableDictionary *response = [NSMutableDictionary dictionary];
[ClassObject getDataWithBlock:^(BOOL succeeded, NSError *error){
if (succeeded)
{
[response setObject:#"update succeded" forKey:#"updateKey"];
reply(response);
}
else
{
if (error)
{
[response setObject:[NSString stringWithFormat:#"update failed: %#", error.description] forKey:#"updateKey"];
reply(response);
}
else
{
[response setObject:#"update failed with no error" forKey:#"updateKey"];
reply(response);
}
}
}];
}
dispatch_after(dispatch_time( DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 180), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[UIApplication sharedApplication] endBackgroundTask:watchKitHandler];
});
I get this error:
"The UIApplicationDelegate in the iPhone App never called reply() in -[UIApplicationDelegate application:handleWatchKitExtensionRequest:reply:]"
So I guess I have to call reply() immediately and the only way to send fresh network data after WatchKit wakes up the parent app is to use MMWormhole?
To make sure that your asynchronous data fetch does not return immediately (without calling reply), you may try the following:
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply
{
__block UIBackgroundTaskIdentifier watchKitHandler;
watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:#"backgroundTask"
expirationHandler:^{
watchKitHandler = UIBackgroundTaskInvalid;
}];
NSMutableDictionary *response = [NSMutableDictionary dictionary];
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[ClassObject getDataWithBlock:^(BOOL succeeded, NSError *error){
if (succeeded)
{
[response setObject:#"update succeded" forKey:#"updateKey"];
reply(response);
}
else
{
if (error)
{
[response setObject:[NSString stringWithFormat:#"update failed: %#", error.description] forKey:#"updateKey"];
dispatch_semaphore_signal(sema);
reply(response);
}
else
{
[response setObject:#"update failed with no error" forKey:#"updateKey"];
dispatch_semaphore_signal(sema);
reply(response);
}
}
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_after(dispatch_time( DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 1), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[UIApplication sharedApplication] endBackgroundTask:watchKitHandler];
});
}
Always refer to official documentation. Official Documentation
The following code works for me.
__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithName:#"MyTask" expirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task, preferably in chunks.
[ClassObject getDataWithBlock:^(BOOL succeeded, NSError *error){
if (succeeded)
{
[response setObject:#"update succeded" forKey:#"updateKey"];
reply(response);
}
else
{
if (error)
{
[response setObject:[NSString stringWithFormat:#"update failed: %#", error.description] forKey:#"updateKey"];
reply(response);
}
else
{
[response setObject:#"update failed with no error" forKey:#"updateKey"];
reply(response);
}
}
}];
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
I think you got your code mixed up. You need to move the beginBackgroundTaskWithName to be inside your handleWatchKitExtensionRequest Make it the first thing you do, then call your function.
Simplified example:
-(void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply{
UIApplication *app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier bgTask __block = [app beginBackgroundTaskWithName:#"watchAppRequest" expirationHandler:^{
NSLog(#"Background handler called. Background tasks expirationHandler called.");
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
//do your background task(s) here
if([requestString isEqualToString:#“myRequest"]){
//send reply back to watch
reply();
}
//end background task
[app endBackgroundTask:bgTask];
bgTask=UIBackgroundTaskInvalid;
}

How to register a device in ios

i am developing a app and whenever my app is installed on a iDevice, i must register that device, in the server through a post Web service, how to do that, This is what so far i have done:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([application respondsToSelector:#selector(isRegisteredForRemoteNotifications)])
{
// iOS 8 Notifications
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[application registerForRemoteNotifications];
}
else
{
// iOS < 8 Notifications
//[application registerForRemoteNotificationTypes:
// (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}
return YES;
}
and then i wrote the following,
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *devToken = [[[[deviceToken description]
stringByReplacingOccurrencesOfString:#"<"withString:#""]
stringByReplacingOccurrencesOfString:#">" withString:#""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
[self registerDeviceTokenWithServer:devToken];
}
Next this method
-(void)registerDeviceTokenWithServer :(NSString*)deviceToken{
[NSThread detachNewThreadSelector:#selector(registerDeviceInBackground:)
toTarget:self withObject:deviceToken];
}
and now i need to register the mobile through the device token in the following method through a post call Web service, how to do that,
-(void)registerDeviceInBackground :(NSString*)deviceToken
{
I need to write the code here a post call method.
}
If any code help is there, is well appreciated.
You can write this:
-(void)registerDeviceTokenWithServer :(NSString*)deviceToken{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSURL *s = [NSURL URLWithString: #"www.apple.com/yoururl"];
NSMutableURLRequest *requestURL = [NSMutableURLRequest requestWithURL:s cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:90.00];
[requestURL setHTTPMethod:#"POST"];
NSError *error = [[NSError alloc] init];
if ([parameter isKindOfClass : [NSString class]]) {
[requestURL setHTTPBody:[devToken dataUsingEncoding:NSUTF8StringEncoding]];
}
NSHTTPURLResponse *response;
NSError *error1;
NSData *apiData = [NSURLConnection sendSynchronousRequest:requestURL returningResponse:&response error:&error1];
dictionaryData = [NSJSONSerialization JSONObjectWithData:apiData options:kNilOptions error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
if ([[dictionaryData objectForKey:#"status"] isEqualToString:#"success"]) {
//Post successful
}
else if([[apiDataBack objectForKey:#"status"] isEqualToString:#"error"]){
//error
}
});
});
}
Above code will post the device token asynchronously.
Hope this helps.. :)

Resources