orphaned UILocalNotification - confirmed - ios

I have an app I am working on with allows the user to set and remove UILocalNotifications. In the course of developing this I have added and removed UILocalNotifications for testing and it seems to be working.
However I am seeing strange behavior where, after deleting my app from the device and running it again without setting any notifications, I will get a UILocalNotification. This notification was not set in this fresh install (checked through adding a breakpoint in my notification setup method).
Is it possible that I have an orphaned UILocalNotification from a previous install (yes, it seems highly unlikely to me too).
I've tried debugging this by setting the notification alertBody to something specific to each new install but this unique string doesn't get displayed in the alert. For example:
notif.alertBody = [NSString stringWithFormat:#"Alert for: %#", alertName];
Has anyone seen this sort of behavior before?
Update: Just confirmed orphaned UILocalNotifications: deleted the app from the device and ran the code below in my rootViewController on viewDidAppear. I get the following output in the Console:
2013-03-14 14:20:07.439 TestApp[16606:907] found alert: uigffhy
2013-03-14 14:20:07.444 TestApp[16606:907] found alert: uigffhy
Where this user was from some previous install. Ugh.
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (UILocalNotification *notif in notificationArray) {
NSDictionary * info = notif.userInfo;
NSString * name = [info objectForKey:#"sequenceName"];
NSLog(#"found alert: %#", name);
}

Just detect if it's a fresh install (using NSUserDefaults) and do the following in applicationDidFinishLaunching:
[[UIApplication sharedApplication] cancelAllLocalNotifications];

Related

Not receiving push form Urban Airship on iOS

I'm trying to get my iOS devices to receive push notifications again, but it's not really working out.
The context in which I'm working:
My project setup
Platforms I need to support: iOS8+
UA version I'm using: 8.0.1 (installed using Cocoapods)
Background modes (Remote notifications) and Push Notifications are ON
My code
Added didReceiveRemoteNotification: to the Application delegate: √
Added UNUserNotificationCenter support (and implemented the delegate methods) for iOS10: √
Configured an UAConfig: √
UA takes off: √
UAPush has all the notificationOptions and has userPushNotificationsEnabled set to YES: √
Here are a few snippets of my code:
(in applicationDidFinishLaunching:)
if (UNUserNotificationCenter.class) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
DLog(#"There was an error trying to request authorization for push: %#", error);
}
}];
} else {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings
settingsForTypes:(UIUserNotificationTypeAlert
| UIUserNotificationTypeSound
| UIUserNotificationTypeBadge)
categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
UAConfig *config = [UAConfig config];
config.inProduction = self.urbanAirshipInProduction;
if(self.urbanAirshipInProduction) {
config.productionAppKey = self.urbanAirshipKey;
config.productionAppSecret = self.urbanAirshipSecret;
} else {
config.developmentAppKey = self.urbanAirshipKey;
config.developmentAppSecret = self.urbanAirshipSecret;
}
[UAirship takeOff:config];
UAPush *pusher = [UAirship push];
pusher.notificationOptions = (UANotificationOptionAlert |
UANotificationOptionBadge |
UANotificationOptionSound);
pusher.pushNotificationDelegate = self;
pusher.userPushNotificationsEnabled = YES;
With the above code I was expecting to receive calls to applicationDidReceiveRemoteNotification:fetchCompletionHandler: and UNUserNotificationCenterDelegate methods for iOS10.
But alas, none of them methods even dared to get called.
I have no clue as to why push won't get pushed to my devices. I checked the App in UA and Installed, Opted in and Background are all green when I search for my device token.
The problem arises with both iOS 8,9 and iOS10. But I'm not sure if this is really an OS thing.
Why?
Because I found a support ticket here and somewhere to the bottom "aboca_ext" (just search the page for his/her username) says:
Hi guys, I found my problem, I was cleaning up my cache when my application was starting, but after UA initiated sqlite db, and by this I was deleting their db. After I fixed that, everything worked as it should.
Now that's interesting because my project also uses SQLCipher, I'm wondering if that produces some kind of conflict (even though I'm not clearing any cache or whatsoever), but I'm not seeing any errors produced by either SQLCipher or UA.
Another funny (actually not so funny) note is that I think UA actually started failing after installing it using Cocoapods, but again--I'm not really sure if that's the problem.
The Urban Airship SDK takes care of registering with UNUserNotificationCenter for you. You should be able to remove registration calls. I don't think it should be causing problems for you, but it could prevent some features such as OOTB categories from working.
As for push notification events, I would recommend listening using the push delegate on the UAPush instance instead of the factory methods or the UNUserNotificationCenter. The UA delegate methods are called across all OS versions. Hopefully it will help simplify your event handling code.
Deleting the sql lite database could cause some issues with reporting, but I would expect push to continue to work. Could you turn on verbose logging and the channel registration payload to see if opt_in is set to true? You can enable verbose logging on the UAConfig object.

Trying to Write An Auto Answer App to Test iPhone

I'm trying to write an app to auto answer an iphone when there are incoming calls.
The app can be launched by the user and run in the background.
I'm trying to use the IOS Private APIs to do this, but no success.
This is for testing purpose only and won't be submitted to the app store so using private APIs shouldn't be a problem. The phones aren't jailbroken though.
This is what I have in my AppDelegate.m file (didFinishLaunchingWithOptions):
id callCenterId = [TUCallCenter sharedInstance];
NSLog(#"callCenterId: %#", callCenterId);
TUCallCenter *object = [[TUCallCenter alloc] init];
NSLog(#"object: %#", object);
[object handleCallModelStateChanged: ^{
NSLog(#"this is an incoming call");
}];
When I run the app, I do see some outputs in the debug panel:
2016-02-01 10:32:38.849 AutoAnswer[312:63056] callCenterId: <TUCallCenter: 0x134642b40>
2016-02-01 10:32:38.851 AutoAnswer[312:63056] object: <TUCallCenter: 0x1346496c0>
But nothing is shown when I dial the phone when the app is in the foreground. I can't even get that to work, so forget about making it work in the background.
Any help would be appreciated.

adding usernotification category without permission dialog popping up

Is it possible to add interactive notification categories without the notifications permissions dialog popping up? The problem is if they hit "Don't Allow" on the original notifications permissions dialog, but then later change the notification setting manually, your categories never get added and there doesn't seem to be anyway to add them back. Is there anyway to separate the two?
I've tried:
UIMutableUserNotificationAction* snoozeAction = [[UIMutableUserNotificationAction alloc] init];
[snoozeAction setIdentifier:#"snooze_action_id"];
[snoozeAction setTitle:#"Snooze"];
[snoozeAction setActivationMode:UIUserNotificationActivationModeBackground];
[snoozeAction setDestructive:NO];
[snoozeAction setAuthenticationRequired:NO];
UIMutableUserNotificationCategory* SnoozeCategory = [[UIMutableUserNotificationCategory alloc] init];
[SnoozeCategory setIdentifier:kNotifCategory];
[SnoozeCategory setActions:#[snoozeAction] forContext:UIUserNotificationActionContextDefault];
[SnoozeCategory setActions:#[snoozeAction] forContext:UIUserNotificationActionContextMinimal];
NSSet* categories = [NSSet setWithArray:#[SnoozeCategory]];
//NOT asking for permission to send any type of notifications here, just making sure our categories get saved
UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeNone categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
As you can see im setting the notification settings to UIUserNOtificationTypeNone, but the permissions dialog still pops up.
From the docs on registerUserNotificationSettings:
The first time your app launches and calls this method, the system asks the user whether your app should be allowed to deliver notifications and stores the response. Thereafter, the system uses the stored response to determine the actual types of notifications you may use.
...
Calling this method with a new user settings object replaces the previous settings request.
So I think what you can do is wrap your code in a method that gets called on each app launch (maybe in application:didFinishLaunchingWithOptions: or even applicationDidBecomeActive:). The user will only be prompted once and if they reject and enable later your new method should add the correct settings.

Rate this app funtionlity

i am trying to provide the rate this app functionality into my application hence i added the below code
- (void)gotoReviews
//------------------
{
NSString *str = #"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa";
str = [NSString stringWithFormat:#"%#/wa/viewContentsUserReviews?", str];
str = [NSString stringWithFormat:#"%#type=Purple+Software&id=", str];
str = [NSString stringWithFormat:#"%#APPid", str];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
}
str = [NSString stringWithFormat:#"%#APPid", str]; here i have to mention my app id.i see the appid into the provisioning portal as following 546F5QMTE4.com.XXXX.XXXX into the APp id section.
Is that the "546F5QMTE4" string need to placed? am i right is that correct id?
please let me know
You can do this in many ways:
Direct approach:
#define APP_ID XXXXX //id from iTunesConnect
NSString *reviewURL = [NSString stringWithFormat:#"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%d",APP_ID];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];
Try with Appirator in app delegate:
[Appirater setAppId:#"552035781"];
[Appirater setDaysUntilPrompt:1];
[Appirater setUsesUntilPrompt:10];
[Appirater setSignificantEventsUntilPrompt:-1];
[Appirater setTimeBeforeReminding:2];
[Appirater setDebug:YES];
You can get source: Here.
Add Appirater.h and Appirater.m to your project.
For more information about integration: Here
:)
No, it is not that number. You have to go to the iTunesConnect -> Manage Your Apps, choose your app, then look under "App Information" for Apple ID (digits only).
Of course be sure that you have actually a record for your app. If not, just make it (Add New App button).
iRate is best https://github.com/nicklockwood/iRate
The one that I use and works wonders on iOS 5+ (also available for Mac OS X, but this answer is focused on the iOS portion) and up on all devices (iPad, iPhone, iPod Touch) is iRate.
It uses a uialertview and storekit to ask the user for a rating (or to remind them later). Everything is customizable, from the name of the Cancel Button Title to the Interval at which it reminds the user.
By default, iRate automatically opens when certain requirements are met (ex. app launched X number of times, user passed X number of levels), but you can also use a variety of methods and your own logic (with the help of iRate methods) to manually display an iRate popup.
Setup
To install,
just drag the header (.H) file the implementation (.M) file, and the iRate Bundle (for localization) into your project.
Import the header in your AppDelegate: #import "iRate.h"
Add the StoreKit Framework to your project - More on StoreKit from Apple Documentation
Add the following method to your app delegate: + (void)initialize
The properties can be set in the initialize method, however none of them are required (iRate can automatically find all of this information).
No, it isn't. It's rather a numeric ID with a few digits, something like this:
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=389801252&pageNumber=0&sortOrdering=1&type=Purple+Software
This will only be live when your application has been approved by Apple and it's already on the AppStore (in case of an intentionally delayed launch).
Furthermore, the way you're composing that poor URL string is simply horrible. Don't abuse format strings! You have a constant string here, so you don't even need any call to + [NSString stringWithFormat:]. Even if you wanted to alter the app ID, you could do that using one single formatting statement:
NSString *str = [NSString stringWithFormat:#"http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=%#&pageNumber=0&sortOrdering=1&type=Purple+Software", appID];

Cannot remove an observer <MKUserTrackingBarButtonItem

- (void)viewWillAppear:(BOOL)animated
{
MKUserTrackingBarButtonItem *trackingBarButtonItem = [[MKUserTrackingBarButtonItem alloc]initWithMapView:_mapView];
NSArray *barButtonItems = [NSArray arrayWithObjects:trackingBarButtonItem, nil];
mapToolbar.items = barButtonItems;
...
}
Code works fine on iPhone, but on iPad when view is unloading I get an error:
Cannot remove an observer <MKUserTrackingBarButtonItem 0x9cc0930> for the key path
"controlSize" from <UIButton 0x991b420> because it is not registered as an observer.'
I contacted Apple DTS and their answer was:
"To the best of my knowledge there is no workaround for this in the current shipping SDK. I would check the latest iOS SDK beta though and see if this is still an issue."

Resources