I'm currently trying to make a RSS like iPhone application using MWFeedParser https://github.com/mwaterfall/MWFeedParser to parse my xml feed. Currently I'm trying to implement a background fetch into my app. When there are new items the user gets a local notification. I'm having a hard time checking if there are new entries in my RSS feed I'm currently using the code below. parsedItems is an NSArray which is automatically filled when [feedparser parse] is called. Now the problem is that parsedItems.count always returns zero although I refresh my feed. Any ideas?
In my app delegate I have the following function:
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
NewsTableViewController *viewController = [[NewsTableViewController alloc] init];
[viewController fetchNewDataWithCompletionHandler:^(UIBackgroundFetchResult result) {
completionHandler(result);
}];
}
And in my NewsTableViewController class I have the function:
-(void)fetchNewDataWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSArray *oldItems;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *objectData = [defaults objectForKey:#"parsedItems"];
if(objectData != nil)
{
oldItems = [NSKeyedUnarchiver unarchiveObjectWithData:objectData];
oldItems = [oldItems sortedArrayUsingDescriptors:
[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:#"date"
ascending:NO]]];
}
// Refresh data
[feedParser stopParsing];
[parsedItems removeAllObjects];
[feedParser parse];
NSLog(#"old:%lu", oldItems.count);
NSLog(#"new:%lu", parsedItems.count);
NSLog(#"ding:%lu", self.itemsToDisplay.count);
if (parsedItems.count == oldItems.count) {
completionHandler(UIBackgroundFetchResultNoData);
NSLog(#"No data.");
}
else {
[UIApplication sharedApplication].applicationIconBadgeNumber++;
[self sendNotification];
completionHandler(UIBackgroundFetchResultNewData);
[defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:parsedItems] forKey:#"parsedItems"];
[defaults synchronize];
NSLog(#"New data was fetched.");
}
}
Related
I suppose that this is duplicate but I can not figure it out.
I have to call other app from my iOS app using openUrl method. After finishing its work the other app must return to my app using the same method. I figure out how to call the other App and its open my App too. My problem is how to intercept the return to my App. I need to check the value from query string.
I find that method handleOpenURL intercepts return and I can handle my query string.
And here I am stuck - how to use that info inside my ViewController? I set breakpoint in viewDidLoad but it was not hit. Which method I have to use?
EDIT:
My Code is (inside AppDelegate):
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSLog(#"url recieved: %#", url);
NSLog(#"query string: %#", [url query]);
NSLog(#"host: %#", [url host]);
NSLog(#"url path: %#", [url path]);
NSDictionary *dict = [self parseQueryString:[url query]];
NSLog(#"query dict: %#", dict);
return YES;
}
- (NSDictionary *)parseQueryString:(NSString *)query {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:6];
NSArray *pairs = [query componentsSeparatedByString:#"&"];
for (NSString *pair in pairs) {
NSArray *elements = [pair componentsSeparatedByString:#"="];
NSString *key = [[elements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *val = [[elements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[dict setObject:val forKey:key];
}
return dict;
}
Which works fine.
Inside my ViewController (VC):
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self setNeedsStatusBarAppearanceUpdate];
// Instantiate App singleton
singApp = [PESsingApplication sharedInstance];
#try {
// Localize resources using currently saved setting for language
[self setLocalizedResources];
// Init visual buttons
[self baseInit];
// Add code for keyboard management
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardHide:)
name:UIKeyboardWillHideNotification
object:nil];
CGRect screenRect = [[UIScreen mainScreen] bounds];
_screenHeight = screenRect.size.height;
_screenWidth = screenRect.size.width;
}
#catch (NSException *exception) {
[self throwUnknownException:exception];
}
}
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
My url:
URL identifier: xx.mydomain.MyUrlScheme
URL shcemes: MyUrlScheme
I have breakpoints inside my VC (on each of the method shown above).
I use following string to call other app: #"otherApp://openApp?param1=value1&callbackUrl=MyUrlScheme";
They call me from the otherApp using callbackUrl param.
You need to make your own custom URL, please look below
How to implement Custom URL Scheme
Defining your app's custom URL scheme is all done in the Info.plist file. Click on the last line in the file and then click the "+" sign off to the right to add a new line. Select URL Types for the new item. Once that's added, click the grey arrow next to "URL Types" to show "Item 0". Set your URL identifier to a unique string - something like com.yourcompany.yourappname.
After you've set the URL identifier, select that line and click the "+" sign again, and add a new item for URL Schemes. Then click the grey arrow next to "URL Schemes" to reveal "Item 0". Set the value for Item 0 to be your URL scheme name.
Handling Custom URL Calls
In order for your app to respond when it receives a custom URL call, you must implement the application:handleOpenURL method in the application delegate class:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
// your code
}
Parsing the Custom URL
There are several parts to a URL:
scheme://host/path?query
The parts to the URL can be retrieved through the NSURL object that is passed into the application:handleOpenURL method. If you have a fairly simple URL naming scheme and want to allow access to specific pages/keys, you can just use the host name:
Custom URL Value of [url host]:
myapp://page1 page1
myapp://page2 page2
myapp://otherPage otherPage
To pass data into your app, you'll want to use the query string. Here's a simple method for parsing the query string from the url:
- (NSDictionary *)parseQueryString:(NSString *)query {
NSMutableDictionary *dict = [[[NSMutableDictionary alloc] initWithCapacity:6] autorelease];
NSArray *pairs = [query componentsSeparatedByString:#"&"];
for (NSString *pair in pairs) {
NSArray *elements = [pair componentsSeparatedByString:#"="];
NSString *key = [[elements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *val = [[elements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[dict setObject:val forKey:key];
}
return dict;
}
Testing The Custom URL
You can easily test your URL scheme in the simulator. Just add a test button to one of your views, and implement the IBAction method for it as follows:
- (IBAction)getTest:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"myappscheme://test_page/one?token=12345&domain=foo.com"]];
}
Then in your app delegate, implement the application:handleOpenURL method:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSLog(#"url recieved: %#", url);
NSLog(#"query string: %#", [url query]);
NSLog(#"host: %#", [url host]);
NSLog(#"url path: %#", [url path]);
NSDictionary *dict = [self parseQueryString:[url query]];
NSLog(#"query dict: %#", dict);
return YES;
}
Finally if you are looking method to receive your data anywhere you can use this two scenario.
You can simple use Local notification or NSUserDefault
NSUserDefault
- (BOOL)application:(UIApplication *)application handleopenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSUserDefaults *userDefaults=[[NSUserDefaults alloc] init];
[userDefaults synchronize];
NSString *status = [defaults stringForKey:#"any status"];
}
Local notification
- (BOOL)application:(UIApplication *)application handleopenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:VAL, #"value", nil];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
If your viewDidLoad is not called perfectly try in viewWillAppear or viewDidAppear method.
For example purpose:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSDictionary *dict = [self parseQueryString:[url query]];
NSLog(#"query dict: %#", dict);
// add dictionary to standardUserDefaults for saving purpose, like
[[NSUserDefaults standardUserDefaults] setObject:dict forKey:#"DicKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
// add code for navigation/present view controller
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
YourViewController *yourController = (YourViewController *)[mainStoryboard
instantiateViewControllerWithIdentifier:#"YourViewControllerID"];
self.window.rootViewController = yourController;
return YES;
}
for retrieve
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSMutableDictionary *mutableRetrievedDictionary = [[[NSUserDefaults standardUserDefaults] objectForKey:#"DicKey"] mutableCopy];
// here parse the dictionary and do your work here, when your works is over
// remove the key of standardUserDefaults
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"DicKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Store the status from other app in NSUserdefaults, when the ViewController of your app launches fetch the status into a NSString from NSUserdefaults and rise it as an alert.
Call the handleopenURL in appdelegate
- (BOOL)application:(UIApplication *)application handleopenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSUserDefaults *defaults=[[NSUserDefaults alloc] init];
[defaults synchronize];
NSString *status = [defaults stringForKey:#"status string from other app"];
}
I'm having an issue handling the notification payload on some device. I'm sending push notifications to my users through Parse Cloud functions.
I'm using the below method to capture the notification and storing its payload so that the user can view all the received notifications in a dedicated view. On my personal device I always get the notification and it is saved correctly, on my friend's device though the notification arrive but if the App is in background the payload is not saved, while if the App is in foreground the payload is saved.
Can this be an issue of the device itself? Or maybe something related to the phone provider (I have h3g and he have Vodafone)?
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
// Parse push handler will show a UIAlertView
[PFPush handlePush:userInfo];
if (application.applicationState == UIApplicationStateInactive) {
// tha app is inactive, transitioning to or from the background
completionHandler(UIBackgroundFetchResultNoData);
} else if (application.applicationState == UIApplicationStateBackground) {
// tha app is running in background
// add the notification to the notificationsArrayRecord
NSDate *now = [[NSDate alloc]init];
NSDictionary *aps = userInfo[#"aps"];
NSString *alertMessage = aps[#"alert"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *notificationsArrayRecord = [[defaults arrayForKey:#"notificationsArrayRecord"] mutableCopy];
[notificationsArrayRecord addObject:#[now,alertMessage]];
[defaults setValue: notificationsArrayRecord forKey:#"notificationsArrayRecord"];
// update the notifications counter
NSInteger pushCount = [[NSUserDefaults standardUserDefaults] integerForKey: #"pushCount"];
pushCount ++;
[defaults setInteger: pushCount forKey:#"pushCount"];
[defaults synchronize];
completionHandler(UIBackgroundFetchResultNewData);
} else {
// the app is running in foreground
// add the notification to the notificationsArrayRecord
NSDate *now = [[NSDate alloc]init];
NSDictionary *aps = userInfo[#"aps"];
NSString *alertMessage = aps[#"alert"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *notificationsArrayRecord = [[defaults arrayForKey:#"notificationsArrayRecord"] mutableCopy];
[notificationsArrayRecord addObject:#[now,alertMessage]];
[defaults setValue: notificationsArrayRecord forKey:#"notificationsArrayRecord"];
// update the notifications counter
NSInteger pushCount = [[NSUserDefaults standardUserDefaults] integerForKey: #"pushCount"];
pushCount ++;
[defaults setInteger: pushCount forKey:#"pushCount"];
[defaults synchronize];
completionHandler(UIBackgroundFetchResultNewData);
// refresh the menu buttons and the notification counter
[[NSNotificationCenter defaultCenter] postNotificationName:#"appDidReceiveNotificationWhileActive" object:nil];
}
}
I guess the problem is how you handle the application state UIApplicationStateInactive. In this case, you are not storing the information. You should also store it in this case, because the app can apparently be in this state, when you receive notifications. This also explains, why it fails sometimes.
Also see this question, that states the app is in state UIApplicationStateInactive sometimes, when the device receives a notification.
You should refactor your code to store the data in all cases:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
// Parse push handler will show a UIAlertView
[PFPush handlePush:userInfo];
// add the notification to the notificationsArrayRecord
NSDate *now = [[NSDate alloc]init];
NSDictionary *aps = userInfo[#"aps"];
NSString *alertMessage = aps[#"alert"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *notificationsArrayRecord = [[defaults arrayForKey:#"notificationsArrayRecord"] mutableCopy];
[notificationsArrayRecord addObject:#[now,alertMessage]];
[defaults setValue: notificationsArrayRecord forKey:#"notificationsArrayRecord"];
// update the notifications counter
NSInteger pushCount = [[NSUserDefaults standardUserDefaults] integerForKey: #"pushCount"];
pushCount ++;
[defaults setInteger: pushCount forKey:#"pushCount"];
[defaults synchronize];
if (application.applicationState == UIApplicationStateInactive) {
// the app is inactive, transitioning to or from the background
completionHandler(UIBackgroundFetchResultNoData);
} else if (application.applicationState == UIApplicationStateBackground) {
// the app is running in background
completionHandler(UIBackgroundFetchResultNewData);
} else {
// the app is running in foreground
completionHandler(UIBackgroundFetchResultNewData);
// refresh the menu buttons and the notification counter
[[NSNotificationCenter defaultCenter] postNotificationName:#"appDidReceiveNotificationWhileActive" object:nil];
}
}
Update:
I am not sure about calling completionHandler(UIBackgroundFetchResultNoData) in applicationState (no idea what this is good for), but maybe you need to call completionHandler(UIBackgroundFetchResultNewData) instead, also in this case, to get the data stored.
Also make sure you configured everything properly to receive notifications in background, [see this] answer(https://stackoverflow.com/a/31450953/594074).
My application is webview.
The normal it load page http://staging.nhomxe.vn.
But when server send a notify, and attachmented a link. Webview will open this link.
My application activity normal. Then, i add Navigation Controller to ViewControler.
When Server send notify, my webview notify error at [vc.webView loadRequest:urlRequest]; , and application auto exit.
My code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound)];
UILocalNotification *localNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (localNotif) {
// launched from notification
NSLog(#"Co notify!!!");
NSString *message = [localNotif valueForKey:#"link"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:message forKey:#"LINK"];
} else {
// from the springboard
NSLog(#"Khong co notify!!!");
}
return YES;
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(#"My token: %#",deviceToken);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:deviceToken forKey:#"TOKEN"];
}
- (void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(#"Error: %#",error);
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (void)application:(UIApplication*)application didReceiveRemoteNotification:
(NSDictionary*)userInfo
{
NSURL *url ;
NSLog(#"Received notification: %#", userInfo);
NSDictionary *data = [ userInfo objectForKey:#"aps"];
for(NSString *key in data) {
NSString *info = [data objectForKey:key];
NSLog(#"thong tin nhan dc: %# : %#", key, info);
}
NSString *message = [userInfo valueForKey:#"link"] ;
//NSArray *info = [message componentsSeparatedByString:#"&#"];
//NSString *body = [info objectAtIndex:0];
//NSString *link = [info objectAtIndex:1];
NSLog(#"Thong tin Link: %#",message);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:message forKey:#"LINK"];
ViewController *vc = (ViewController *)self.window.rootViewController;
if(message == NULL)
{
url = [NSURL URLWithString:#"http://staging.nhomxe.vn"];
}else
{
url = [NSURL URLWithString:message];
}
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[vc.webView loadRequest:urlRequest];
[vc.webView3 loadRequest:urlRequest];
}
#end
My error:
2014-08-28 14:51:59.374 NhomXe[30379:907] Thong tin Link: http://staging.nhomxe.vn/org/instance_message/conversation-detail.xhtml?post=13001628&orgId=190000168#vehicletracking
2014-08-28 14:52:14.950 NhomXe[30379:907] -[UINavigationController webView]: unrecognized selector sent to instance 0x1d5c8350
2014-08-28 14:52:14.958 NhomXe[30379:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController webView]: unrecognized selector sent to instance 0x1d5c8350'
*** First throw call stack:
(0x314e22a3 0x3913e97f 0x314e5e07 0x314e4531 0x3143bf68 0xd687f 0x3353d585 0x3353dfa5 0x33f53305 0x314b7173 0x314b7117 0x314b5f99 0x31428ebd 0x31428d49 0x34fa52eb 0x3333e301 0xd6ad9 0x39575b20)
libc++abi.dylib: terminate called throwing an exception
Your rootViewController is returning a UINavigationController which is used to manage a navigation stack, that is represented by an array of view controllers.
To get your view controller try getting the topViewController, for example:
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
ViewController *vc = (ViewController *)navigationController.topViewController;
You can also get a array of all view controller that navigation manages by:
NSLog(#"%#", navigationController.viewControllers);
Update your UI on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
// make sure vc is a weak refernace to avoid retain cycle
[vc.webView loadRequest:urlRequest];
[vc.webView3 loadRequest:urlRequest];
});
I have an NSMutableArray inside of my AppDelegate, and I'm attempting to save it to NSUserDefaults. The NSMutableArray (strainsfinal) contains a list of favorited items. I want this list to save, and be present even if the app is shut down, and then restarted. Does anyone know why my code isn't working (not saving my data)? See below:
AppDelegate.m
-(void)updateStrains:(NSDictionary *)item
{
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataSave = [currentDefaults objectForKey:#"strains"];
if (strainsfinal != nil)
{
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataSave];
if (oldSavedArray != nil)
strainsfinal = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
strainsfinal = [[NSMutableArray alloc] init];
}
}
EDIT: Appdelegate.m So I've changed my above method to the method below (and I thought it should work), but the app crashes, saying: "Terminating app due to uncaught exception 'NSInvalidArguementException', reason: 'NSConcreteAttributedString initwithString: nil 'value'.
What am I missing?!
-(void)updateStrains:(NSDictionary *)item {
NSData *dataSave = [NSKeyedArchiver archivedDataWithRootObject:strainsfinal];
[[NSUserDefaults standardUserDefaults] setObject:dataSave forKey:#"strains"];
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:#"arrayupdated" object:self userInfo:nil];
NSLog(#"updated strains %#",strainsfinal);
}
You must add
[currentDefaults synchronize];
each time after you save something to userDefaults;
But for such kind of data is better to use .plist files.
Check documentation for more info.
EDITED Code:
-(void)updateStrains:(NSDictionary *)item {
NSData *dataSave = [NSKeyedArchiver archivedDataWithRootObject:item[#"strainsfinal"]];
[[NSUserDefaults standardUserDefaults] setObject:dataSave forKey:#"strains"];
// NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
// [nc postNotificationName:#"arrayupdated" object:self userInfo:nil];
NSLog(#"updated strains %#",strainsfinal);
[[NSUserDefaults standardUserDefaults] synchronize]; // this will save you UserDefaults
}
use following method :
NSUserDefaults *userDef = [NSUserDefaults standardUserDefaults];
[userDef setObject:array1 forKey:#"DataArra1"];
[userDef setObject:array2 forKey:#"DataArr2"];
[userDef synchronize];
To retrieve the information:
NSUserDefaults *userDef = [NSUserDefaults standardUserDefaults];
NSArray *arrayText2 = [userDef objectForKey:#"DataArra1"];
NSArray *arrayText1 = [userDef objectForKey:#"DataArr2"];
You should archive NSArray before saving.
[[NSUserDefaults standardUserDefaults]
setObject:[NSKeyedArchiver archivedDataWithRootObject:yourArray]
forKey:#"yourArray"];
and unarchive when getting from NSUserDefaults.
NSData *data = [currentDefaults objectForKey:#"yourArray"];
if (data != nil)
{
NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
I want to use a UISwitch to enable/disable push notifications. Like in Tweetbot.
Does anyone know how to trigger that?
You can also do it in the following way.
create a IBOutlet for UISwitch
#property (strong, nonatomic) IBOutlet *pushNotificationSwitch;
and in Action method, store the value in NSUserDefaults.
- (IBAction)pushNotificationSwitchChanged:(id)sender
{
NSNumber *switch_value = [NSNumber numberWithBool:[self.pushNotificationSwitch isOn]];
[[NSUserDefaults standardUserDefaults] setObject:switch_value forKey:RECIEVE_APNS];
[[NSUserDefaults standardUserDefaults] synchronize];
}
and check it in viewdidload.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSNumber *sett = [[NSUserDefaults standardUserDefaults] valueForKey:RECIEVE_APNS];
if( [sett boolValue] )
{
[self.pushNotificationSwitch setOn:YES];
}
else{
[self.pushNotificationSwitch setOn:NO];
}
}
and In AppDelegate.m, add the following code
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSNumber *sett = [[NSUserDefaults standardUserDefaults] objectForKey:RECIEVE_APNS];
if( [sett boolValue] )
{
int currentBadgeCount = [[NSUserDefaults standardUserDefaults] integerForKey:#"BadgeCount"];
//Set the baadge count on the app icon in the home screen
int badgeValue = [[[userInfo valueForKey:#"aps"] valueForKey:#"badge"] intValue];
[UIApplication sharedApplication].applicationIconBadgeNumber = badgeValue + currentBadgeCount;
[[NSUserDefaults standardUserDefaults] setInteger:badgeValue + currentBadgeCount forKey:#"BadgeCount"];
NSString *alertString = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
NSString *playSoundOnAlert = [NSString stringWithFormat:#"%#", [[userInfo objectForKey:#"aps"] objectForKey:#"sound"]];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%#",[[NSBundle mainBundle] resourcePath],playSoundOnAlert]];
NSError *error;
if (alertString.length > 0)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"App Name" message:alertString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 1;
[audioPlayer play];
[alert show];
}
}
}
enter code here
You can not do that directly from the application. If you want to do this, you need to make the UISwitch send the information to your backend, store this information in your database and stop sending push notifications to this user.
An app registers for Push Notifications (APN) when it first launches. You cannot have it initialize APNs with a switch once it has already launched. You can however code your app that a switch can choose to do "something" with the user interface once a APN is received.
For example, you can have this code:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
NSString *alert = [apsInfo objectForKey:#"alert"];
// do what you need with the data...
[[NSNotificationCenter defaultCenter] postNotificationName:#"ReceivedNotificationAlert" object:self];
}
You can use your UISwitch to either do something, or not, with the NSNotification "ReceivedNotificationAlert". For example:
if(switchAPNprocess.on){
// process APN
}
else {
// ignore APN
}