ios 8 Push notification not opening app from background (Pushkit) - ios8

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
viewcontroller2 *historyVC = [storyboard instantiateViewControllerWithIdentifier: #"second"];
self.window.rootViewController = historyVC;
[self.window makeKeyAndVisible];
}
My app not opening from background to foreground but as per apple doc they said app will be come foreground.

The following method
- pushRegistry:didUpdatePushCredentials:forType:
is invoked when push notification is received.
until and unless user launches the app, we cant open the app.
when u open app. make preferences to show your respective view controller.

Using push kit, newer your app will get open automatically. that would not come to foreground from background or terminated state.
Your app will only gets active in background mode for some 30 seconds and you would be able to do rest of work whichever is needed. ( For example setting some values in Database etc )

Related

Cocoa NSBundle loadNibNamed deprecated

I'm developing a Cocoa App and I noticed NSBundle loadNibNamed is deprecated.
I'm trying to use a Sheet to show some config options. I'm using an AppController and the Config Sheet is a NIB created separately.
This is my code.
- (IBAction)showConfig:(id)sender{
if (!_config) {
[NSBundle loadNibNamed:#"Config" owner:self];
}
[NSApp beginSheet:self.config modalForWindow:[[NSApp delegate] window] modalDelegate:self didEndSelector:NULL contextInfo:NULL];
}
Using that code, the config Sheet opens and closes perfectly.
When I switch this [NSBundle loadNibNamed:#"Config" owner:self]; to [[NSBundle mainBundle] loadNibNamed:#"Config" owner:self topLevelObjects:nil]; the config Sheet still works fine.
My real problem is when I want to close it. The app crashes throwing this error:
Thread 1:EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
This is my IBAction to close the config Sheet.
- (IBAction)closeConfig:(id)sender{
[NSApp endSheet:self.config];
[self.config close];
self.config = nil;
}
Once I skip the deprecated line, what do I need to do to close the config sheet correctly?
I'm running Yosemite and Xcode 6.4.
Is the window property in your app delegate class weak? If so, see this answer. The not-deprecated method that you are now using requires your controller to have strong references to the top level objects.

Handoff not working from native app to website

My devices:
iPad Mini (latest), iOS 8 dp5.
Macbook Air, Yosemite dp5.
I have Handoff working between the two above devices. Safari, Mail, Messages, Calendar, etc. all handoff with no problems.
I can even handoff between my website on the Air and my native app on the iPad.
What I can't do yet is go from my native app on the iPad to my website in Safari on my Air.
For the first view controller that loads in my native app, I have this:
- (void)viewDidLoad
{
[super viewDidLoad];
NSUserActivity *webHandoff = [[NSUserActivity alloc] initWithActivityType:#"com.myApp.iphone.staging.webbrowsing"];
webHandoff.webpageURL = [NSURL URLWithString:#"http://staging.myApp.com"];
[webHandoff becomeCurrent];
}
In my app's Info.plist file, I have this:
<key>NSUserActivityTypes</key>
<array>
<string>com.myApp.iphone.staging.webbrowsing</string>
</array>
Am I missing something or do I have something configured incorrectly?
Thanks for any help!
I made two significant changes to my code:
1) configure/destroy and set the NSUserActivity object in viewDidAppear/disappear as opposed to viewDidLoad:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSUserActivity *webHandoff = [[NSUserActivity alloc] initWithActivityType:#"com.myApp.iphone.staging.web-browsing"];
webHandoff.webpageURL = self.handoffWebpageURL;
[self setUserActivity:webHandoff];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self.userActivity invalidate];
}
2) Since UIViewController is a subclass of UIResponder and UIResponders have a userActivity property, instead of calling [webHandoff becomeCurrent] I simply called [self setUserActivity:webHandoff];
Not sure why moving it out of viewDidLoad had any impact, and not sure why I need to set it to the viewController's instance of NSUserActivity, but the changes above give me a solid and reliable handoff experience throughout my entire app.

Has there been a change to the way Mac OSX Mavericks handles CFBundleURLName "Custom url" launches for applications?

I created an app which is launched from a custom url in any OSX browser. This worked just fine by adding a standard CFBundleURLName entry to the app's plist.
My application works by reading by parsing some of the parameters on the custom url and then reacting to them.
So for example with a custom url of:
foobar://param1/param2/param3
When clicking on the above url in a browser, OSX would launch my app and pass the actual custom url itself as the first argument to the app. Therefore in the app I could read the first arg and get the url the opened the app, and parse it for params I need.
This works fine in OSX 10.5-10.8, but in 10.9 Mavericks it appears to work slightly differently. Namely that if the application is not already running, it still launches the app but does not pass the custom url as first argument - so the app thinks it's just been launched manually by the user (such as selecting it from launchpad) rather than directly from a browser.
Weirdly, if the application is already open, then clicking the custom url DOES send the url string over to the app as first argument and functionality within the app occurs as expected.
I've tested this across 10.6->10.9 with new and old versions of my app and all exhibit the same behaviour. All work fine on first launch with versions before 10.9 Mavericks, but in 10.9 they don't get the url passed as first arg but then work on 2nd click once already running.
If anyone could shed some light on this I would be very grateful.
Where do you set up your URL handler? It needs to happen early. If you currently have it in applicationDidFinishLaunching, try to move it to applicationWillFinishLaunching.
The following works for me and logs the URL at launch even when the app is not running before I open the URL in Safari, for example. When I change WillFinishLaunching to DidFinishLaunching, I see exactly the behavior you describe.
#implementation AppDelegate
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
[appleEventManager setEventHandler:self andSelector:#selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
NSAppleEventDescriptor *obj = [event descriptorForKeyword:keyDirectObject];
DescType type = [obj descriptorType];
if (type == typeChar) {
NSData *data = [obj data];
if (data) {
NSString *urlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlString];
NSLog(#"url: %#", url);
}
}
}
#end

How to force NSArrayController to reload MOC contents to reflect latest fresh data

I am working on a Mac & iOS App, with iCloud CoreData in between to synchronize the data.
When I update some thing from iOS App, and the updates are already migrated to the PersistentStore in Mac App while the Mac App is running. The problem is I cannot find an effective way to force the NSArrayController to reload all data from the store.
tried -(void) fetch:(id)sender; only can see the delete or added entity, but the updated model property not refreshed...
Please help. Thanks
If you see the latest data in the managed object context, but not in the array controller, you want:
[_yourManagedObjectContext processPendingChanges];
[_yourArrayController fetchWithRequest:nil merge:YES error:&error];
[_yourArrayController rearrangeObjects];
I use this in a Mac/iOS iCloud app to update the Mac app's data when the iCloud store changes.
Following is the reply from Apple's Developer Technical support. It worked for me. Thanks all for providing solutions.
For the OS X app, when reloadFetchResults is called, you can ask the NSManagedObjectContext to reset itself and perform the fetch again.
- (void)reloadFetchedResults:(NSNotification *)note
{
NSDictionary *userInfoDict = [note userInfo];
NSManagedObjectContext *moc = self.coreDataController.mainThreadContext;
// this only works if you used NSMainQueueConcurrencyType
// otherwise use a dispatch_async back to the main thread yourself
//
[moc performBlock:^{
[self mergeiCloudChanges:userInfoDict forContext:moc];
[moc reset];
[self.tableArrayController fetch:self];
}];
}
I've found that
[self.managedObjectContext reset];
[myArrayController fetch:self];
forces my NSTableView (with NSArrayController) to re-populate and display newly processed NSManagedObjects.
in case someone else finds this...
in my case, I was building the array from user interaction (not Core Data), and then trying to show the tableView when they were done (on the same window)... and of course... seeing nothing!
[arrayController rearrangeObjects];
just before I wanted to show the tableView fixed it for me.

Remove push from notificationcenter after app has been opened

When I send out a PUSH notification to my app, it stays in the notification center in iOS 5.
How can I remove the notification from the notification center from within the app?
Clearing the badge clears the notifications from the notification center.
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Clear application badge when app launches
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}
This only works if the number changes. So to make it work in case badge is already zero, set it to some value and clear it again after a delay.
- (void)applicationWillEnterForeground:(UIApplication *)application {
if([[UIApplication sharedApplication] applicationIconBadgeNumber] == 0)
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Clear application badge when app launches
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}
Doesn't work if you set and clear in the same method.
It is not possible to remove the notification from the notification center from within the app because in iOS5, notifications properties are displayed by apps, in :
Settings -> Notifications -> The app -> Notification Center (YES/NO).

Resources