In my application i want to display the remote notification in UILabel. So I'm trying pass the notification message form the "Appdelegate" to my storyboard its not working please tell me how to resolve this one.
My "Appdelegate" code:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSString *messag = [[userInfo description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#"<>"]];
[[NSUserDefaults standardUserDefaults] setObject: messag forKey:#"message"];
[[NSUserDefaults standardUserDefaults]synchronize];
NSLog (#"message %#", [[NSUserDefaults standardUserDefaults] objectForKey:#"message"]);
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
personalnottypoliticalViewController *ringingVC = [mainstoryboard instantiateViewControllerWithIdentifier:#"notifymess"];
[self.window setRootViewController: ringingVC];
}
When i print my data its coming like:
message {
aps = {
alert = home;
badge = 3;
sound = "";
};
}
in my viewcontroller i have used like this.
self.message.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"message"];
NSLog (#"message %#", [[NSUserDefaults standardUserDefaults] objectForKey:#"message"]);
In the above data i need only the "Alert" value how to get the alert value and store into the data please tell me is that possible to do and how to achieve this one. I'm stack here for long not please give some ideas to achieve this one.
Thanks.
The description method creates a string representation of an object for logging purposes, but you wouldn't use it in that way to access the contents of the object.
From the Apple documentation -
The userInfo dictionary contains the aps key whose value is another
dictionary. Although you should not need the information in the aps
dictionary, you can retrieve its contents using the following keys:
alert—The value is either a string for the alert message or a
dictionary with two keys: body and show-view. The value of the body
key is a string containing the alert message and the value of the
show-view key is a Boolean. If the value of the show-view key is
false, the alert’s View button is not shown. The default is to show
the View button which, if the user taps it, launches the app.
badge —A
number indicating the quantity of data items to download from the
provider. This number is to be displayed on the app icon. The absence
of a badge property indicates that any number currently badging the
icon should be removed.
sound —The name of a sound file in the app
bundle to play as an alert sound. If “default” is specified, the
default sound should be played.
So, you can use the code from this answer - How to handle push notifications if the application is already running?
NSDictionary *aps=(NSDictionary *)[userInfo objectForKey:#"aps"];
NSString *message;
id alert = [aps objectForKey:#"alert"];
if ([alert isKindOfClass:[NSString class]]) {
message = alert;
} else if ([alert isKindOfClass:[NSDictionary class]]) {
message = [alert objectForKey:#"body"];
}
Hi try using this code
NSDictionary *dict=userInfo;
NSString *messag=[[[dict objectForKey:#"message"]objectForKey:#"aps"]objectForKey:#"alert"];
Related
I have an app that can receive a push notification which is opened in a UIAlertView in the AppDelegate. The app will normally open to a tableview of items (if no push notification is present). Each item can be selected to view more detail about the item. How do I go about getting the detailed view to display with information from the push notification of an item? I saw this functionality in FaceBook Messenger where an incoming message launches the conversation from the specific user.
Thanks in advance
Push notifications can include embedded JSON, not just text, so you can put a small amount of command data into a push notification.
Here's some code that shows a message being passed in a push notification as well as an URL and a number that we only expect to see if the URL is there:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSString *message = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
NSString *url = [userInfo objectForKey:#"url"];
if ([url length]) {
NSNumber *fooCount = [userInfo objectForKey:#"Foo"];
You can now do whatever your app wants to do with this data.
I want to open a ViewController only once when the app start for the very first time. Below is my code. The problem is when I am writing YES to NSUserdefaults , doing a synchronise , and then closing the app. in Xcode using simulator , the value is not updated to Yes.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"isFirstLaunch"])
{
// app already launched
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],#"isFirstLaunch", nil]];
[[NSUserDefaults standardUserDefaults]synchronize];
}
else
{
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],#"isFirstLaunch", nil]];
[[NSUserDefaults standardUserDefaults]synchronize];
}
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"isFirstLaunch"])
{
NSLog(#"first time");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LASplashUserSettingViewController *splash = [storyboard instantiateViewControllerWithIdentifier:#"splash"];
[self.window.rootViewController presentViewController:splash animated:NO completion:nil];//
}
}
Why is NSUserDefaults not saving my values?
Have followed above and many other links. what am i missing here?
Thanks,
what am i missing here?
-registerDefaults: doesn't do what you think it does. Use -setBool:forKey: instead.
-registerDefaults: is used to ensure that values exist for certain keys in the defaults system. There's no need to call -synchronize after that method because the values in the registration domain are never saved. You probably meant to use that method to set up the default value YES for isFirstLaunch, but your code checks the value for the key before you register the default value! which defeats the purpose of the method. Proper use would be to call -registerDefaults: first, and then check the value associated with the key, and if the value is YES then call -setBool:forKey: to save the value NO.
A simpler option to detect the first launch would be to invert the question. Skip the -registerDefaults: call altogether and change the key to appHasRunPreviously. If no value is stored for a given key, -boolForKey: will return NO. If that happens, you know that this is the first time the app is running, and you should save YES for that key using -setBool:forKey:.
This is how you use NSUserDefaults in AppDelegate.m
+ (void)initialize
{
// Register defaults for first time
NSMutableDictionary *defs = [NSMutableDictionary dictionary];
[defs setObject:[NSNumber numberWithBool:YES] forKey:#"isFirstLaunch"];
[[NSUserDefaults standardUserDefaults] registerDefaults:defs];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if([defaults boolForKey:#"isFirstLaunch"])
{
// Do your stuff here
[defaults setBool:NO forKey:#"isFirstLaunch"];
[defaults synchronize];
}
}
Don't set isFirstLaunch back to YES in the else-condition if you only want the view to be shown once.
You can try this
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:#"AlreadyLaunched"];
[[NSUserDefaults standardUserDefaults]boolForKey:#"AlreadyLaunched"]
I'm implementing an in-app purchase feature. In addition to Apple Store standard purchase flow, I have another receipt validation from my own server side. Sometimes, the purchase procedure is complete on Apple side and the app exist before my server validates the receipt.
So I store the receipt in NSUserDefaults. And whenever applicationDidBecomeActive, I would check if there's pending receipt in NSUserDefaults. If yes, I would like to pop up an alert, asking user whether to continue completing the purchase. If user canceled, then I would remove the receipt cancel the purchase. Otherwise, I would direct user to a purchase view, and do the rest of work.
Previously, I did the checking inside AppDelegate ApplicationDidBecomeActive. It seems not to be a good practice. I then try to move the code into MainViewController, catch AppicationDidBecomeActive notification in init. But I'm not sure what's the correct way of doing so? I try to catch the event with selector:#selector(resumePurchase:) and here's my resumePurchase code
- (void)resumePurchase:(NSNotification*)notification {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSData *purchaseDocument = (NSData*)[userDefaults objectForKey:#"lastPurchaseDocument"];
if (!purchaseDocument) {
NSString *message = [NSString stringWithFormat:NSLocalizedString(#"You have an incomplete purchase in the app, do you want to continue the payment?",#"resume purchase.")];
self.resumePurchaseAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Resume Payment",#"alter title")
message:message
delegate:self
cancelButtonTitle:NSLocalizedString(#"Cancel",#"Cancel caption")
otherButtonTitles:NSLocalizedString(#"Continue",#"altert approve button"), nil];
[self.resumePurchaseAlert show];
}
}
This seems ok so far. I'm stuck at the Continue button handler
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView == self.resumePurchaseAlert) {
if (buttonIndex == 0) { // Cancel
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults removeObjectForKey:kPurchaseDocument];
[userDefaults synchronize];
}
if (buttonIndex == 1) { // Continue
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *purchaseDocument = (NSDictionary*)[userDefaults objectForKey:kPurchaseDocument];
NSData *purchasedReceipt = [purchaseDocument objectForKey:kPurchasedReceipt];
NSString *purchasedFeature = [purchaseDocument objectForKey:kPurchasedFeature];
if (purchasedFeature && purchasedReceipt) {
// here I want to redirect the view to PurchaseViewController
}
}
}
}
I don't know how can I redirect the view to PurchaseViewController in an elegant way...
in other UIViewController check value that you saved in NSUserDefaults and do nabvigation according to it.
I have an ios app which loads a webpage to show data. I use push notifications for receiving news and I want that depending of which push is received, goes to one page or other (sections inside the same page).
In the text received in push notification, I add a word before the text, something like:
page1 - text
page2 - text2
page3 - text3
...
In android I take the first word and add to the webpage url: www.page.com/ + pageAdded
In iOs I think I haveto add this code to didFinishLaunchWithOptions function. But I don't know where I should add the new code for passing the arguments. I add my function so you can tell me where to put it.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:#"CityInfoPush" accessGroup:nil];
udid = [keychainItem objectForKey:(__bridge id)kSecValueData];
//if udid is empty , that means we need to generate one and save it on KeyChain
if([udid length] == 0){
NSLog(#"No CFUUID found. Creating one...");
//creating CFUUID
CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault);
NSString *cfuuidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));
NSLog(#"Device CFUUID created is : %#" , cfuuidString);
//saving CFUUID on KeyChain
[keychainItem setObject: cfuuidString forKey:(__bridge id)kSecValueData];
//retrieving CFUUID from KeyChain and passing it to udid String.
udid = [keychainItem objectForKey:(__bridge id)kSecValueData];
}
//For reseting the keyChain (testing)
//[keychainItem resetKeychainItem];
NSLog(#"Password Saved in KeyChain is: %#" , udid);
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
} else {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
// Let the device know we want to receive push notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
return YES;
}
I add the message to the payload for sending it to the apple server like this:
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
I am trying to get the alert text (message) in ios like this, but always fails and crash the app:
NSString *text=[[lastNotif valueForKeyPath:#"aps"][0] objectForKey:#"alert"];
First, you can check if you app has been launched with a puch notification in your application:
didFinishLaunchingWithOptions: function with :
if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey])
What I do is save this notification in the userDefaults :
[[NSUserDefaults standardUserDefaults] setObject:[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey] forKey:#"notificationReceived"];
[[NSUserDefaults standardUserDefaults] synchronize];
Then in the viewDidLoad where you want to catch your push notification, check if you have one in memory :
NSDictionary *lastNotif = [[NSUserDefaults standardUserDefaults] objectForKey:#"notificationReceived"];
if (lastNotif != nil)
{
//handle what you want to do with your notification
//now don't forget to clean userDefaults
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"notificationReceived"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
I have created a photography assignment generator app using dreamweaver/phonegap with some finishing touches in xcode.
I have set up a settings bundle where the user can set a daily reminder on on off. it is preset to OFF, as i would rather not annoy people who don't want it.
Because i have done this using dreamweaver, I can't find a way to access the settings bundle, so the user has to go to settings, flick the switch, and reboot the app to have it take effect.
What I would like to do is have the app ask them the first time the app is launched whether or not they would like to set up a daily reminder. If they tap yes, it should set the reminder setting to ON/YES, if no, it should continue on with the default set to no.
it would be even more awesome if I could have a "Maybe Later" button.
I am not great at programming, and it was a lot of work for me to get this working(thanks to help from the great folks on here and other sites on the net)
I have tried using various IF/THEN, but I can't get it to work.
So here is what I have so far...would appreciate it greatly if any of you would be able to help me figure this out.
Thank you
Noel Chenier
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOtions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:
UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults =[NSDictionary dictionaryWithObject:#"NO" forKey:#"enableNotifications"];
[defaults registerDefaults:appDefaults];
[defaults synchronize];
UILocalNotification *localNotif= [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSLog(#"Recieved Notification %#",localNotif);
}
/*NSArray *keyArray = [launchOptions allKeys];
if ([launchOptions objectForKey:[keyArray objectAtIndex:0]]!=[nil)
{
NSURL *url = [launchOptions objectForKey:[keyArray objectAtIndex:0]];
self.invokeString = [url absoluteString];
}*/
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
This is a pretty simple task, especially considering you're already using NSUserDefaults. All you need to do is store a BOOL in your defaults every time the app launches. For example:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOtions:(NSDictionary *)launchOptions {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
if(![defaults boolForKey:#"firstLaunch"]) {
//this key has never been set - this is the first launch
[defaults setBool:YES forKey:#"firstLaunch"];
//show your alert here that you only want to show on the
//first application launch
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Some Title"
message:#"Some message" delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Some Button", #"Another Button", #"One More Button",
nil];
[alert show];
}
}