Update UIMutableUserNotificationAction Button Title on Remote Push Notification - objective-c

I have an app in iOS where I am sending quick surveys to the users. I want to make use of the new funcionality in iOS 8 where the user interacts directly on the push notification. The user will receive the survey question and respond.
I know you have to construct your actions and categories when starting the app. I have written my code and have been able to successfully perform this so far.
Now, the thing is that the text on the action button will change based on the survey question. I am including the keys and text for the action buttons on the JSON I am sending, but I haven't been able to change the action button titles when receiving the notification.
Is there a way to do this? Here is my code:
I define global variables:
//This will help configure the interactive notifications, so that the user can reply to push notification from out of the app
NSString * const notificationCategoryIdent = #"SURVEY";
NSString * const notificationActionPositiveButton = #"POSITIVE_BUTTON";
NSString * const notificationActionNegativeButton = #"NEGATIVE_BUTTON";
In my AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if(pushNotificationPayload) {
urlPushData2 = #"Application was closed";
[self application:[UIApplication sharedApplication] didReceiveRemoteNotification:pushNotificationPayload];
}
//Registrar tipos de aviso para Push Notifications
//if ([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)]){
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0){ //Before iOS 8
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
UIUserNotificationTypeSound |
UIUserNotificationTypeAlert)];
}
else {
// define notification actions (In case of categorized remote push notifications)
positiveButton = [[UIMutableUserNotificationAction alloc] init];
[positiveButton setActivationMode:UIUserNotificationActivationModeForeground];
[positiveButton setTitle:notificationActionPositiveButton];
[positiveButton setIdentifier:notificationActionPositiveButton];
[positiveButton setDestructive:NO];
// this action wil be executed without necessity of passcode authentication (if locked)
[positiveButton setAuthenticationRequired:NO];
negativeButton = [[UIMutableUserNotificationAction alloc] init];
[negativeButton setActivationMode:UIUserNotificationActivationModeForeground];
[negativeButton setTitle:notificationActionNegativeButton];
[negativeButton setIdentifier:notificationActionNegativeButton];
[negativeButton setDestructive:NO];
// this action wil be executed without necessity of passcode authentication (if locked)
[negativeButton setAuthenticationRequired:NO];
// define Categories (In case of categorized remote push notifications)
UIMutableUserNotificationCategory *actionCategory;
actionCategory = [[UIMutableUserNotificationCategory alloc] init];
[actionCategory setIdentifier:notificationCategoryIdent];
[actionCategory setActions:#[positiveButton, negativeButton]
forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObject:actionCategory];
UIUserNotificationType types = (UIUserNotificationTypeAlert|
UIUserNotificationTypeSound|
UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types
categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
//Boolean value for temporary app interruptions
temporaryInactivity = FALSE;
return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"remote notification: %#",[userInfo description]);
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
NSString *alert = [apsInfo objectForKey:#"alert"];
//NSLog(#"Received Push Alert: %#", alert);
NSString *sound = [apsInfo objectForKey:#"sound"];
NSLog(#"Received Push Sound: %#", sound);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
application.applicationIconBadgeNumber = [[apsInfo objectForKey:#"badge"] integerValue];
self.mainUrl = [userInfo valueForKey:#"url"];
urlPushData = [NSString stringWithFormat:#"%#", mainUrl];
//NSLog(#"urlPushData: %#",urlPushData);
self.mainUrl2 = [userInfo valueForKey:#"url2"];
urlPushData2 = [NSString stringWithFormat:#"%#", mainUrl2];
//NSLog(#"urlPushData2: %#",urlPushData2);
NSString *category = [apsInfo objectForKey:#"category"];
NSLog(#"category: %#", category);
if ([category isEqualToString:notificationCategoryIdent]) {
NSLog(#"button1: %#", [apsInfo objectForKey:#"positiveButton"]);
NSLog(#"button2: %#", [apsInfo objectForKey:#"negativeButton"]);
NSString *stringPositiveButton = [apsInfo objectForKey:#"positiveButton"];
NSString *stringNegativeButton = [apsInfo objectForKey:#"negativeButton"];
[positiveButton setTitle:stringPositiveButton];
[negativeButton setTitle:stringNegativeButton];
}
else {
if (![urlPushData2 isEqualToString:#"Application was closed"]) {
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber - 1;
[[NSUserDefaults standardUserDefaults] setObject:urlPushData2 forKey:#"pushNotificationURL"];
[[NSUserDefaults standardUserDefaults] setObject:alert forKey:#"pushNotificationURLName"];
[[NSUserDefaults standardUserDefaults]synchronize];
if (NSClassFromString(#"UIAlertController")) {
//make and use a UIAlertController
UIAlertController *alertView = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:#"%#",appNameLink]
message:[NSString stringWithFormat:#"Has recibido una nueva nota: %#. ¿Deseas verla?",alert]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *Cancel = [UIAlertAction actionWithTitle:#"No"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber - 1;
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"pushNotificationURL"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"pushNotificationURLName"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
];
UIAlertAction *OK = [UIAlertAction actionWithTitle:#"Sí"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber - 1;
self.url = [[NSUserDefaults standardUserDefaults] objectForKey:#"pushNotificationURL"];
self.urlName = [[NSUserDefaults standardUserDefaults] objectForKey:#"pushNotificationURLName"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"pushNotificationURL"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"pushNotificationURLName"];
[[NSUserDefaults standardUserDefaults]synchronize];
[self setupNavigationControllerApp];
}
];
[alertView addAction:Cancel];
[alertView addAction:OK];
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertView animated:YES completion:nil];
}
else {
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:[NSString stringWithFormat:#"%#",appNameLink] message:[NSString stringWithFormat:#"Has recibido una nueva nota: %#. ¿Deseas verla?",alert] delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Sí", nil];
[alertView show];
}
} else {
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber - 1;
//self.url = [[NSUserDefaults standardUserDefaults]objectForKey:#"pushNotificationURL"];
self.url = urlPushData2;
self.urlName = alert;
[self setupNavigationControllerApp];
}
}
}
- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:notificationActionPositiveButton]) {
//Testing the action button
self.url = #"http://www.google.com";
self.urlName = #"hello";
[self setupNavigationControllerApp];
}
else if ([identifier isEqualToString:notificationActionNegativeButton]) {
//Testing the action button
self.url = #"http://www.yahoo.com";
self.urlName = #"goodbye";
[self setupNavigationControllerApp];
}
// Must be called when finished
completionHandler();
}
And this is my JSON:
{"aps":
{"alert":"Who's your favorite pop singer?",
"badge":1,
"sound":"default",
"category":"SURVEY",
"positiveButton":"Katy Perry",
"negativeButton":"Miley Cyrus"
},
"url":"http://www.pretechmobile.com",
"url2":"http://goo.gl/U9p1y"
}

I am sorry, but you cannot change the title of the buttons dynamically. They are tied to the category in which they are stored when you register for notifications.
A possible workaround could be to present the two options in the text of the message labeled with an 'A' and a 'B' and have your buttons with titles 'Option A' and 'Option B'. Something like this:
---------------------------------
|Who's your favorite pop singer?|
|A: Katy Perry B: Miley Cyrus|
---------------------------------
| Option A | Option B |
---------------------------------
Also, If you have yes/no questions, you can create a category for them with the options 'Yes' and 'No' and label your notifications with this category.
I hope this helps a bit.

Related

Why is my Progress HUD not displaying as expected

I'm trying to develop a 'passwordless' registration form using a QRCode. The background processing works (can authenticate user), but noting happens visually until the registration is complete and the user is redirected to the apps main ViewController, however, A progress dialog with spinner is supposed to appear during the registration process but it doesn't. If, I manually input the credentials and press 'authenticate', everything works as expected, Just not after scanning the QR code.
Please see code below:
#interface ViewControllerRegister (){
JGProgressHUD *HUD;
NSString *regid;
NSString *regpin;
NSMutableDictionary *dicto;
}
//OPEN QRCODE READER VC
- (IBAction)scanAction:(id)sender
{
if ([QRCodeReader supportsMetadataObjectTypes:#[AVMetadataObjectTypeQRCode]]) {
static QRCodeReaderViewController *vc = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
QRCodeReader *reader = [QRCodeReader readerWithMetadataObjectTypes:#[AVMetadataObjectTypeQRCode]];
vc = [QRCodeReaderViewController readerWithCancelButtonTitle:#"Cancel" codeReader:reader startScanningAtLoad:YES];
vc.modalPresentationStyle = UIModalPresentationFormSheet;
});
vc.delegate = self;
[vc setCompletionWithBlock:^(NSString *resultAsString) {
// NSLog(#"Completion with result: %#", resultAsString);
}];
[self presentViewController:vc animated:YES completion:NULL];
}
else {
[self showAlert:#"Reader not supported by the current device"];
}
}
//// PARSE THE RETURNED QR CODE DATA
#pragma mark - QRCodeReader Delegate Methods
- (void)reader:(QRCodeReaderViewController *)reader didScanResult:(NSString *)result
{
[self dismissViewControllerAnimated:YES completion:^{
NSURL *stringfromscan = [NSURL URLWithString:result];
dicto = [NSMutableDictionary new];
NSURLComponents *components = [NSURLComponents componentsWithURL:stringfromscan resolvingAgainstBaseURL:NO];
NSArray *queryItems = [components queryItems];
for (NSURLQueryItem *item in queryItems)
{
[dicto setObject:[item value] forKey:[item name]];
}
if ([result rangeOfString:#"eloq"].location == NSNotFound && [result rangeOfString:#"unique"].location == NSNotFound) {
[self showAlert:#"Looks like you've scanned an incorect QR code"];
} else {
self.TextViewUniqueID.text = [dicto objectForKey:#"uniqueid"];
self.TextViewPIN.text = [dicto objectForKey:#"password"];
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self authent];
});
}
}];
}
/// CREDENTIAL VALIDATION OF SORTS
- (void)authent{
NSLog(#"s UNIQUEID %#", self.TextViewUniqueID.text);
NSLog(#"PIN %#", self.TextViewPIN.text);
// [self resignFirstResponder];
int uniqueID = [self.TextViewUniqueID.text length];
int PIN = [self.TextViewPIN.text length];
if (uniqueID < 7 || PIN < 6){
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Error!"
message:#"Your UniqueID or PIN is too short."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"Try Again" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
[self clear];
}else{
/*
HUD WILL NOT DISPLAY AFTER READING QR CODE
*/
HUD = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark];
HUD.textLabel.text = #"Authenticating";
[HUD showInView:self.view];
[self PostJson:self.TextViewUniqueID.text :self.TextViewPIN.text];
}
}

Post Notification is not called from application didFinishLaunchingWithOptions

I am getting push notification from server but my postNotification is not being called. It is correctly entering in if statement which states that type == 1. All the user defaults are correctly stored but the notification is not being called. I put the break point as well as an alert in the function of view controller which is called by the post notification. But it never being called. Here is my code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(launchOptions != nil)
{
NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
NSString *type = [dictionary objectForKey:#"type"];
if([[NSString stringWithFormat:#"%#",type]integerValue]==1)
{
[[NSUserDefaults standardUserDefaults]setObject:[[dictionary objectForKey:#"aps"] valueForKey:#"alert"] forKey:#"message"];
[[NSUserDefaults standardUserDefaults]setObject:[dictionary objectForKey:#"senderid"] forKey:#"senderID"];
[[NSUserDefaults standardUserDefaults]setObject:[dictionary objectForKey:#"sendername"] forKey:#"sendername"];
[[NSUserDefaults standardUserDefaults]setObject:[dictionary objectForKey:#"userimage"] forKey:#"pushImage"];
[[NSUserDefaults standardUserDefaults]synchronize];
NSLog(#"message is %#",[[dictionary objectForKey:#"aps"] valueForKey:#"alert"]);
NSLog(#"senderID is %#",[dictionary objectForKey:#"senderid"]);
NSLog(#"sender name is %#",[dictionary objectForKey:#"sendername"]);
[[NSNotificationCenter defaultCenter] postNotificationName:#"pushNotification" object:nil userInfo:launchOptions];
}
}
#ifdef __IPHONE_8_0
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
#endif
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
application.applicationIconBadgeNumber=0;
[UIApplication sharedApplication].statusBarHidden = NO;
[UIApplication sharedApplication].networkActivityIndicatorVisible=FALSE;
return YES;
}
Find the answer of my own question. Here is the code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[self window] setBackgroundColor:[UIColor whiteColor]];
[FBLoginView class];
self.mainNavigationController = (UINavigationController*)self.window.rootViewController;
if(launchOptions != nil)
{
NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
NSString *type = [NSString stringWithFormat:#"%#",[[[dictionary valueForKey:#"aps"] valueForKey:#"json"] valueForKey:#"type"]];
NSLog(#"type is %#",type);
if ([type isEqualToString:#"0"]) // 0 means NOW
{
[[NSUserDefaults standardUserDefaults]setObject:[[[dictionary valueForKey:#"aps"] valueForKey:#"json"] valueForKey:#"yadda_sub_type"] forKey:kYaddaSubType_Push];
[[NSUserDefaults standardUserDefaults]setObject:[[[dictionary valueForKey:#"aps"] valueForKey:#"json"] valueForKey:#"user_id"] forKey:kYaddaUserID_Push];
[[NSUserDefaults standardUserDefaults]setObject:[[[dictionary valueForKey:#"aps"] valueForKey:#"json"] valueForKey:#"yadda_id"] forKey:kYaddaID_Push];
ReciversSideVC *reciverControoler = [[ReciversSideVC alloc]init];
[reciverControoler.navigationController setNavigationBarHidden:YES];
[reciverControoler.navigationController setToolbarHidden:YES];
[AppDelegateClass.mainNavigationController pushViewController:reciverControoler animated:NO];
}
else if ([type isEqualToString:#"1"]) // 1 means LATER
{
if (isCalendarScreenOpen==YES)
{
CalendarVC *calendar = [[CalendarVC alloc]init];
[calendar.navigationController setNavigationBarHidden:YES];
[calendar.navigationController setToolbarHidden:YES];
[AppDelegateClass.mainNavigationController pushViewController:calendar animated:NO];
}
}
else if ([type isEqualToString:#"2"]) // 2 means Remind me
{
LandingPageVC *landing = [[LandingPageVC alloc]init];
[landing.navigationController setNavigationBarHidden:YES];
[landing.navigationController setToolbarHidden:YES];
[AppDelegateClass.mainNavigationController pushViewController:landing animated:NO];
}
else if ([type isEqualToString:#"3"]) // 3 means Reply
{
LandingPageVC *landing = [[LandingPageVC alloc]init];
[landing.navigationController setNavigationBarHidden:YES];
[landing.navigationController setToolbarHidden:YES];
[AppDelegateClass.mainNavigationController pushViewController:landing animated:NO];
}
else if ([type isEqualToString:#"4"]) // 4 means Contacts
{
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:#"flag_CallAPI"];
[[NSUserDefaults standardUserDefaults]synchronize];
ContactDetailVC *contactDetails = [[ContactDetailVC alloc]init];
contactDetails.userID = [[[dictionary valueForKey:#"aps"] valueForKey:#"json"] valueForKey:#"user_id"];
contactDetails.phoneNumberFromServer = [[[dictionary valueForKey:#"aps"] valueForKey:#"json"] valueForKey:#"phone_number"];
[contactDetails.navigationController setNavigationBarHidden:YES];
[contactDetails.navigationController setToolbarHidden:YES];
[AppDelegateClass.mainNavigationController pushViewController:contactDetails animated:NO];
}
}
}
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif != nil)
{
NSDictionary *NotificationValue = [localNotif.userInfo objectForKey:#"localPushNotification"];
if (NotificationValue != nil)
{
NSLog(#"Run with notification value: %#", NotificationValue);
[[NSUserDefaults standardUserDefaults]setObject:[NotificationValue valueForKey:#"yadda_sub_type"] forKey:kYaddaSubType_Push];
[[NSUserDefaults standardUserDefaults]setObject:[NotificationValue valueForKey:#"user_id"] forKey:kYaddaUserID_Push];
[[NSUserDefaults standardUserDefaults]setObject:[NotificationValue valueForKey:#"yadda_id"] forKey:kYaddaID_Push];
ReciversSideVC *reciverControoler = [[ReciversSideVC alloc]init];
[AppDelegateClass.mainNavigationController pushViewController:reciverControoler animated:NO];
}
}
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
application.applicationIconBadgeNumber=0;
[UIApplication sharedApplication].statusBarHidden = NO;
[UIApplication sharedApplication].networkActivityIndicatorVisible=FALSE;
return YES;
}

How to hide the Alert Box when the internet connectivity is back.?

I have a music player app in which I am checking for internet connectivity when the app is running. When the connectivity is gone, I am showing an alert message and stopping the song. In case if the connectivity is back, I am again playing the song without user doing anything in it, but the problem is I am unable to hide the alert when the song is played back again. Here is the code:
#import "FirstViewController.h"
CM_EXPORT const CMTime kCMTimeZero;
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize metadatas;
#synthesize toggleButton;
#synthesize slider;
#synthesize mpVolumeView = _mpVolumeView;
#synthesize viewVolume;
- (void)viewDidLoad
{
toggleIsOn=TRUE;
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:self.viewVolume.bounds] ;
[self.viewVolume addSubview:volumeView];
[volumeView sizeToFit];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(IBAction)playButtonPressed:(id)sender
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:TRUE forKey:#"FirstPlay"];
[defaults setBool:YES forKey:#"alertShown"];
if(toggleIsOn){
toggleIsOn=!toggleIsOn;
player = nil;
NSString *stringurl = #"";
stringurl = #"http://majestic.wavestreamer.com:6221/listen.pls";
NSURL *url = [NSURL URLWithString:stringurl];
asset = [AVURLAsset URLAssetWithURL:url options:nil];
playerItem = [AVPlayerItem playerItemWithAsset:asset];
player = [AVPlayer playerWithPlayerItem:playerItem];
player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[playerItem addObserver:self forKeyPath:#"timedMetadata" options:NSKeyValueObservingOptionNew context:nil];
[playerItem addObserver:self forKeyPath:#"status" options:NSKeyValueObservingOptionNew context:nil];
[player play];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(audioSessionInterrupted:) name:AVAudioSessionInterruptionNotification object:nil];
[self.toggleButton setImage:[UIImage imageNamed:#"reload.png"] forState:UIControlStateNormal];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
else {
[self.toggleButton setImage:[UIImage imageNamed:#"playMusic.png"] forState:UIControlStateNormal];
self->player.rate=0.0;
toggleIsOn=!toggleIsOn;
}
}
- (void)audioSessionInterrupted:(NSNotification *)notification
{
NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
NSNumber *interruptionOption = [[notification userInfo] objectForKey:AVAudioSessionInterruptionOptionKey];
switch (interruptionType.unsignedIntegerValue) {
case AVAudioSessionInterruptionTypeBegan:{
// [self.toggleButton setImage:[UIImage imageNamed:#"playMusic.png"] forState:UIControlStateNormal];
// • Audio has stopped, already inactive
// • Change state of UI, etc., to reflect non-playing state
} break;
case AVAudioSessionInterruptionTypeEnded:{
// • Make session active
// • Update user interface
// • AVAudioSessionInterruptionOptionShouldResume option
if (interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
// Here you should continue playback.
[player play];
}
} break;
default:
break;
}
}
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)audioPlayer
{
[player pause];
}
-(void)audioRecorderEndInterruption:(AVAudioRecorder *)audioPlayer
{
[player play];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:TRUE forKey:#"alertShown"];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
internetReachable = [Reachability reachabilityForInternetConnection];
[internetReachable startNotifier];
// check if a pathway to a random host exists
hostReachable = [Reachability reachabilityWithHostName:#"www.apple.com"];
[hostReachable startNotifier];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
[playerItem removeObserver:self forKeyPath:keyPath];
if ([keyPath isEqualToString:#"status"]) {
AVPlayerItem *pItem = (AVPlayerItem *)object;
if (pItem.status == AVPlayerItemStatusReadyToPlay)
{
metadatas.text = #"";
}
}
if ([keyPath isEqualToString:#"timedMetadata"]) {
for (AVAssetTrack *track in playerItem.tracks) {
for (AVPlayerItemTrack *item in player.currentItem.tracks) {
if ([item.assetTrack.mediaType isEqual:AVMediaTypeAudio]) {
NSArray *meta = [playerItem timedMetadata];
for (AVMetadataItem *metaItem in meta) {
NSString *source = metaItem.stringValue;
metadatas.text = source;
}
}
}
}
}
[self.toggleButton setImage:[UIImage imageNamed:toggleIsOn ? #"playMusic.png" :#"stop.png"] forState:UIControlStateNormal];
}
-(IBAction)fbButtonPressed:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://www.facebook.com"];
if (![[UIApplication sharedApplication] openURL:url])
NSLog(#"%#%#",#"Failed to open url:",[url description]);
}
-(IBAction)inButtonPressed:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://www.linkedin.com"];
if (![[UIApplication sharedApplication] openURL:url])
NSLog(#"%#%#",#"Failed to open url:",[url description]);
}
-(IBAction)tweetButtonPressed:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://www.twitter.com"];
if (![[UIApplication sharedApplication] openURL:url])
NSLog(#"%#%#",#"Failed to open url:",[url description]);
}
-(IBAction) sliderChanged:(id)sender
{
}
-(void) checkNetworkStatus:(NSNotification *)notice
{
// called after network status changes
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
switch (internetStatus)
{
case NotReachable:
{
NSLog(#"The internet is down.");
NSLog(#"%d",[defaults boolForKey:#"alertShown"]);
BOOL isAlertShown = [defaults boolForKey:#"alertShown"];
if(isAlertShown)
{
[self showAlert];
}
break;
}
case ReachableViaWiFi:
{
NSLog(#"The internet is working via WIFI.");
BOOL isFirstTimePlayed = [defaults boolForKey:#"FirstPlay"];
if(isFirstTimePlayed)
{
[self playButtonPressed:nil];
}
break;
}
case ReachableViaWWAN:
{
NSLog(#"The internet is working via WWAN.");
[self playButtonPressed:nil];
break;
}
}
}
-(void)showAlert
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:FALSE forKey:#"alertShown"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"Alert" message: #"You have lost data connectivity. Please wait while we try to establish the connection again." delegate: nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
#end
In your method showAlert, you have a reference to the UIAlertView object, alert. Simply save that reference in a property so that you can access it later.
#interface FirstViewController ()
#property (nonatomic, strong) UIAlertView* internetConnectivityAlertView;
#end
-(void)showAlert
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:FALSE forKey:#"alertShown"];
self.internetConnectivityAlertView = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"You have lost data connectivity. Please wait while we try to establish the connection again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[self.internetConnectivityAlertView show];
}
When you do get internet connectivity, simply call
if(self.internetConnectivityAlertView)
{
[self.internetConnectivityAlertView dismissWithClickedButtonIndex:0 animated:YES];
self.internetConnectivityAlertView = nil;
}
to dismiss the alert.
See the API Documentation for UIAlertView.

iOS: Image Will Not Delete From Array

I'm working on an app that behaves like a photo gallery, and I'm implementing the option to have the user delete photos from their gallery. To accomplish this, I decided to place an invisible button over each picture. When the user hits an "Edit" button, the hidden delete buttons over each picture become active. I'm using the same IBOutlet over each of the hidden buttons for simplicity, and I've tagged each button appropriately in Interface Builder. When the user taps the button over the picture, an alert view appears asking if they really want to delete it. If they click yes, I call removeObjectAtIndex. Here is the code I'm using:
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes.");
[self.array removeObjectAtIndex: alertView.tag];
}
[self.user setObject:array forKey:#"images"];
}
The issue here is that when I click "Yes" in the alert view, nothing happens. However, if I tap on the image and click "Yes" a second time, the app crashes, and the debug states:
Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray removeObjectAtIndex:]: index (0) beyond bounds (0)' So, I'm not sure where to go from here, I'm still very new to programming and everything looks correct to me. Any help is much appreciated, thanks!
Here is how I add them into the array:
////start of saving////
- (void)viewWillAppear:(BOOL)animated
{
self.user = [NSUserDefaults standardUserDefaults];
self.array = [[self.user objectForKey:#"images"]mutableCopy];
while(self.array == nil)
{
[self.user setObject:[NSMutableArray arrayWithObject:#""] forKey:#"images"];
self.array = [[self.user objectForKey:#"images"]mutableCopy];
NSLog(#"%#",#"attempting to create an array to store the images in");
}
}
- (void)applicationDidEnterBackground:(UIApplication*)application {
NSLog(#"Image on didenterbackground: %#", imageView);
self.array = [NSMutableArray arrayWithObject:[NSData dataWithData:UIImagePNGRepresentation(imageView.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView2.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView3.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView4.image)]];
[self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView5.image)]];
[self.user setObject:self.array forKey:#"images"];
[user synchronize];
}
- (void)viewDidLoad
{
self.user = [NSUserDefaults standardUserDefaults];
NSLog(#"It is %#", self.user);
self.array = [[self.user objectForKey:#"images"]mutableCopy];
imageView.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:0]];
imageView2.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:1]];
imageView3.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:2]];
imageView4.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:3]];
imageView5.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:4]];
imageView6.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:5]];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:app];
backToGalleryButton.hidden = YES;
tapToDeleteLabel.hidden = YES;
deleteButton1.hidden = YES;
[super viewDidLoad];
}
- (void)viewDidUnload
{
self.user = nil;
}
////end of saving
///// shows the hidden and invisible "delete" button over each photo.
- (IBAction)editButtonPressed:(id)sender {
grabButton.hidden = YES;
editButton.hidden = YES;
backToGalleryButton.hidden = NO;
tapToDeleteLabel.hidden = NO;
deleteButton1.hidden = NO;
}
- (IBAction)deleteButtonPressed:(id)sender {
NSLog(#"Sender is %#", sender);
UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:#"Delete"
message:#"Are you sure you want to delete this photo?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[deleteAlertView show];
int imageIndex = ((UIButton *)sender).tag;
deleteAlertView.tag = imageIndex;
}
- (void)alertView: (UIAlertView *) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex]) {
NSLog(#"User Clicked Yes.");
NSLog(#"Array: %#, index: %d", self.array, alertView.tag);
[self.array removeObjectAtIndex: alertView.tag];
}
[self.user setObject:array forKey:#"images"];
}
#end
EDIT: This is the code I use to put the objects into the UIImageView from the users camera roll:
- (IBAction)grabImage {
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
_popover = [[UIPopoverController alloc] initWithContentViewController:imgPicker];
[_popover presentPopoverFromRect:self.imageView.bounds inView:self.imageView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[self presentModalViewController:imgPicker animated:YES];
}
[self.imgPicker resignFirstResponder];
}
// Sets the image in the UIImageView
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
if (imageView.image == nil) {
imageView.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView2.image == nil) {
imageView2.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView3.image == nil) {
imageView3.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
if (imageView4.image == nil) {
imageView4.image = img;
[picker dismissModalViewControllerAnimated:YES];
[self.popover dismissPopoverAnimated:YES];
return;
}
}
When I added NSLog(#"Array: %#, index: %d", self.array, alertView.tag); just before removeAtIndex the console says 2012-04-03 18:39:39.066 AppName[1631:f803] Array: (null), index: 0. Could that be the cause? I'm not sure why it would be, I think the code looks fine.
Removing the image from the array is not the only step you have to take. Your code is correct for removing the image from the array, which is why you get image out of bounds the second time, but you also need to remove the image from the UI so the user can no longer delete an image that is not there.
There are many oddities with this code but I think the problem is that you are not calling super on your viewwillappear and viewdidload functions. I would get rid of your viewWillAppear method as it serves no purpose.

Push Notification Badge Count Not Updating

this is my code for apple push notification, when the application is running and notification coming i am incrementing the badge count and getting desired result when i click home button, on app icon. but when i am not running my application and notification comes, it didn't auto increment badge count and remains to only 1. the value 1 is coming from server. can any one point out where i am doing wrong. thanks in advance.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
userMessageCounter = #"0";
postType = 0;
joinedStreamChecker = 0;
OwnerValue = 0;
pushValue = 1;
badgeValue =0;
// Override point for customization after application launch.
// Add the navigation controller's view to the window and display.
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)];
//[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
//(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
// [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeNewsstandContentAvailability | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)];
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
{
pushValue = 0;
NSLog(#"notification off");
}
return YES;
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken1 {
NSString *str = [NSString
stringWithFormat:#"%#",deviceToken1];
NSLog(#"%#",str);
self.deviceToken = [NSString stringWithFormat:#"%#",str];
NSLog(#"dev --- %#",self.deviceToken);
self.deviceToken = [self.deviceToken stringByReplacingOccurrencesOfString:#"<" withString:#""];
self.deviceToken = [self.deviceToken stringByReplacingOccurrencesOfString:#" " withString:#""];
self.deviceToken = [self.deviceToken stringByReplacingOccurrencesOfString:#">" withString:#""];
NSLog(#"dev --- %#",self.deviceToken);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSString stringWithFormat: #"Error: %#", err];
NSLog(#"%#",str);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Received notification: %#", userInfo);
//[self addMessageFromRemoteNotification:userInfo];
NSString* alertValue = [[userInfo valueForKey:#"aps"] valueForKey:#"badge"];
NSLog(#"my message-- %#",alertValue);
badgeValue= [alertValue intValue];
[UIApplication sharedApplication].applicationIconBadgeNumber += badgeValue;
//badgeValue = [UIApplication sharedApplication].applicationIconBadgeNumber;
//[UIApplication sharedApplication].applicationIconBadgeNumber=0;
//[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badgeValue];
}
Apple does not keep track of your data for you. It only shows what you tell it to. Thus, you have to store the count on your server, then tell apple the new badge number when you send the alert. Typically this is done by having the app phone home when launched telling your servers to zero out the count of unread notifications.