iOS application launch from INRequestRideIntent extension - ios

I need to implement a ride booking feature via Siri in an application. I managed to add extension to app and now I'm able to communicate with Siri, but I didn't succeed in launching app to continue ride booking process within the application.
So here comes the question, what should be done for launching app from INRequestRideIntent extension?
Thanks in advance!
RideIntentHandler.m
- (void)confirmRequestRide:(INRequestRideIntent *)intent completion:(void (^)(INRequestRideIntentResponse * _Nonnull))completion {
INRideOption *rideOption = [[INRideOption alloc] initWithName:#"blah" estimatedPickupDate:[NSDate dateWithTimeIntervalSinceNow:300]];
rideOption.userActivityForBookingInApplication = [[NSUserActivity alloc] initWithActivityType:#"blahblah"];
INRideStatus *rideStatus = [[INRideStatus alloc] init];
rideStatus.rideOption = rideOption;
rideStatus.estimatedPickupDate = [NSDate dateWithTimeIntervalSinceNow:300];
rideStatus.rideIdentifier = [NSUUID UUID].UUIDString;
INRequestRideIntentResponse *response = [[INRequestRideIntentResponse alloc] initWithCode:INRequestRideIntentResponseCodeSuccess userActivity:nil];
response.rideStatus = rideStatus;
completion(response);
}
AppDelegate.m
- (void)application:(UIApplication *)application handleIntent:(INIntent *)intent completionHandler:(void (^)(INIntentResponse * _Nonnull))completionHandler {
[Utils showCommonAlertWithMessage:#"blah"];
if ([intent isKindOfClass:[INRequestRideIntent class]]) {
[Utils showCommonAlertWithMessage:#"blah"];
}
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
[Utils showCommonAlertWithMessage:#"blah"];
if ([userActivity.interaction.intent isKindOfClass:[INRequestRideIntent class]]) {
NSLog(#"%#", userActivity.userInfo);
[Utils showCommonAlertWithMessage:#"blah"];
}
return YES;
}
- (void)application:(UIApplication *)application didFailToContinueUserActivityWithType:(NSString *)userActivityType error:(NSError *)error {
[Utils showCommonAlertWithMessage:#"blah"];
}

Related

Sinch SDK with VoIP, PushKit, CallKit

I integrated Sinch sdk into my projects with VoIP, PushKit, CallKit. Everything is working fine. But when app is not running in device A and someone(Device B) is calling to it then sometimes in device A I am getting notification with text SIN_INCOMING_CALL . I don't know from where it is coming. But my problem is, I want to open default call screen of iOS device. Sometime it is being opened and sometimes it show notification with this text.
My Appdelegate has following code.
#interface AppDelegate() <SINClientDelegate, SINCallClientDelegate, SINManagedPushDelegate, SINCallDelegate>
#property (nonatomic, readwrite, strong) id<SINManagedPush> push;
#property (strong, nonatomic) id<SINClient> sinchClient;
#property (nonatomic, readwrite, strong) SINCallKitProvider *callKitProvider;
#end
#implementation AppDelegate
- (void)applicationWillEnterForeground:(UIApplication *)application
{
id<SINCall> call = [self.callKitProvider currentEstablishedCall];
if (call) {
//Show call view controller and pass call
}
}
#pragma mark - Remote Notification
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
if (notificationSettings.types != UIUserNotificationTypeNone) { [application registerForRemoteNotifications]; }
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString *newToken = deviceToken.description;
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:#" " withString:#""];
[self.push application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
NSLog(#"My token is: %#", newToken);
//get previously initiated Sinch client
if (!self.sinchClient) { [self initSinchCallConfig]; }
id<SINClient> client = [self sinchClient];
[client registerPushNotificationData:deviceToken];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
[obj_SharedModel setUDID:#""]; //Statuc Device Id just for testing purpose from simulator.
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[self.push application:application didReceiveRemoteNotification:userInfo];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)registerForPushNotifications
{
UIApplication *application = [UIApplication sharedApplication];
if (IS_OS_10_BELOW) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
}
else {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){ dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] registerForRemoteNotifications]; }); }
}];
}
//register for VoIP push
PKPushRegistry *voipRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
voipRegistry.delegate = self;
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
self.push = [Sinch managedPushWithAPSEnvironment:SINAPSEnvironmentAutomatic];
self.push.delegate = self;
[self.push setDesiredPushTypeAutomatically];
[self.push registerUserNotificationSettings];
}
- (void)unRegisterForPushNotifications
{
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
[self.sinchClient unregisterPushNotificationDeviceToken];
}
#pragma mark - IOS 10 UP - UNUserNotificationCenter
//Called when a notification is delivered to a foreground app.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
NSLog(#"User Info : %#",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
//Called to let your app know which action was selected by the user for a given notification.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
completionHandler();
}
#pragma mark - VoIP remote Notifications
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
NSString *newToken = credentials.token.description;
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"VoIP Tokenp is: %#", newToken);
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
NSDictionary *dictPayload = payload.dictionaryPayload;
if ([dictPayload sin_isSinchPushPayload]) {
if (!self.sinchClient) { [self initSinchCallConfig]; }
[self.sinchClient relayRemotePushNotification:dictPayload];
/*
{"aps":{"alert":{"loc-key" : "SIN_INCOMING_CALL"}},"sin" :"ASDAS" }
*/
}
else {
}
}
- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(NSString *)type { }
#pragma mark - SINClient Method
- (void)initSinchCallConfig
{
// Instantiate a Sinch client object
if (!self.sinchClient && [stLoginUserName length]) {
self.sinchClient = [Sinch clientWithApplicationKey:#"dea827c1-1208-45a6-b510-5d1f277d9607" applicationSecret:#"AgxDpf/4X0OrLx1GXv6Quw==" environmentHost:#"sandbox.sinch.com" userId:stLoginUserName];
self.sinchClient.delegate = self;
self.sinchClient.callClient.delegate = self; //for incomming call
[self.sinchClient setSupportCalling:YES];
[self.sinchClient setSupportPushNotifications:YES];
[self.sinchClient setPushNotificationDisplayName:MSG_TITLE];
[self.sinchClient enableManagedPushNotifications];
[self.sinchClient start];
[self.sinchClient startListeningOnActiveConnection];
self.callKitProvider = [[SINCallKitProvider alloc] initWithClient:self.sinchClient];
}
}
#pragma mark - SINClient Delegate
- (void)clientDidStart:(id<SINClient>)client {
NSLog(#"Sinch client started successfully (version: %#)", [Sinch version]);
}
- (void)clientDidFail:(id<SINClient>)client error:(NSError *)error {
NSLog(#"Sinch client error: %#", [error localizedDescription]);
}
- (void)client:(id<SINClient>)client logMessage:(NSString *)message area:(NSString *)area severity:(SINLogSeverity)severity timestamp:(NSDate *)timestamp {
NSLog(#"%#", message);
}
#pragma mark - SINCallClient Delegate
- (void)client:(id<SINCallClient>)client didReceiveIncomingCall:(id<SINCall>)call {
NSLog(#"didReceiveIncomingCall");
CallViewController *callVC = [[CallViewController alloc] initWithNibName:#"CallViewController" bundle:nil];
callVC.call = call;
AppNavigationController *nav = [[AppNavigationController alloc] initWithRootViewController:callVC];
[self.navigationController presentViewController:nav animated:YES completion:nil];
if (call.details.applicationStateWhenReceived == UIApplicationStateActive) { }
else { [callVC btnAcceptCallAction]; }
}
- (void)client:(id<SINClient>)client willReceiveIncomingCall:(id<SINCall>)call {
[self.callKitProvider reportNewIncomingCall:call];
call.delegate = self;
}
#pragma mark - SINManagedPush Delegate
- (void)managedPush:(id<SINManagedPush>)unused didReceiveIncomingPushWithPayload:(NSDictionary *)payload forType:(NSString *)pushType {
if (!self.sinchClient) { [self initSinchCallConfig]; }
[self.sinchClient relayRemotePushNotification:payload];
}
- (void)call:(id<SINCall>)call shouldSendPushNotifications:(NSArray *) pushPairs {
NSLog(#"shouldSendPushNotifications");
}
#pragma mark - SINCall Delegate
- (void)callDidProgress:(id<SINCall>)call {
}
- (void)callDidEstablish:(id<SINCall>)call {
}
- (void)callDidEnd:(id<SINCall>)call { [[self callKitProvider] reportCallEnded:call]; }
#end

Pushkit with Sinch VOIP not working with pushkit

I am trying to implement App-to-App calling with Sinch in my IOS app. I have implemented Pushkit in my iOS app with Sinch but the push notification is not working when the app is in background.
I have two questions.
Do I need another web service to send push notification to my app for incoming app separately or Sinch handles it itself.
If it does handle itself then what am I missing in my code.
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
[self handleLocalNotification:[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]];
self.push = [Sinch managedPushWithAPSEnvironment:SINAPSEnvironmentAutomatic];
self.push.delegate = self;
[self.push setDesiredPushTypeAutomatically];
[self.push registerUserNotificationSettings];
return YES;
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary *)options {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (id<SINClient>)client {
return _sinchClient;
}
-(void)clientDidFail:(id<SINClient>)client error:(NSError *)error{
NSLog(#"fail");
}
-(void)clientDidStart:(id<SINClient>)client{
NSLog(#"Start");
[self voipRegistration];
}
- (void)client:(id<SINClient>)client
logMessage:(NSString *)message
area:(NSString *)area
severity:(SINLogSeverity)severity
timestamp:(NSDate *)timestamp {
// If you want all messages remove the if statement
if (severity == SINLogSeverityCritical) {
NSLog(#"%#", message);
}
}
- (void)initSinchClientWithUserId:(NSString *)userId {
if (!_sinchClient) {
_sinchClient = [Sinch clientWithApplicationKey:#"<my-key>"
applicationSecret:#"<my-secret>"
environmentHost:#"sandbox.sinch.com"
userId:userId];
_sinchClient.delegate = self;
[_sinchClient setSupportCalling:YES];
[_sinchClient startListeningOnActiveConnection];
[_sinchClient enableManagedPushNotifications];
[_sinchClient start];
}
}
- (void)handleLocalNotification:(UILocalNotification *)notification {
if (notification) {
id<SINNotificationResult> result = [self.sinchClient relayLocalNotification:notification];
if ([result isCall] && [[result callResult] isTimedOut]) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Missed call"
message:[NSString stringWithFormat:#"Missed call from %#", [[result callResult] remoteUserId]]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[alert show];
}
}
}
-(void)voipRegistration
{
PKPushRegistry* voipRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
voipRegistry.delegate = self;
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
[_sinchClient registerPushNotificationData:credentials.token];
}
-(void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type{
NSLog(#"invalidated");
}
-(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType: (NSString *)type
{
//notify
NSDictionary* dic = payload.dictionaryPayload;
NSString* sinchinfo = [dic objectForKey:#"sin"];
UILocalNotification* notif = [[UILocalNotification alloc] init];
notif.alertBody = #"incoming call";
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
if (sinchinfo == nil)
return;
dispatch_async(dispatch_get_main_queue(), ^{
[_sinchClient relayRemotePushNotificationPayload:sinchinfo];
});
}
If you integrated Pushkit and Sinch then push notification may can't catch on PushKit's delegate function - didReceiveIncomingPushWithPayload. But you can get push notification on SINManagedPushDelegate's function - didReceiveIncomingPushWithPayload.
Push notification is not coming but you can get incoming call event on there when app is in background. You can trigger local notification if app is in background to let user incoming call know.
Hope that would be helpful for you.

3D touch home screen actions, Launchoptions is nil always even after entering from

Launch options is always nil.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Launch options is always coming nil
//even when I launch from 3D touch shortcut icon
shortcutItemkey = [launchOptions objectForKey:UIApplicationLaunchOptionsShortcutItemKey];
return N0;
}
performActionForShortcutItem delegate method is getting called as usual.
-(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler {
completionHandler([self handleShortcut:shortcutItem]);
}
- (void)shortcutsWithIcon
{
#try
{
UIApplicationShortcutIcon *icon1 = [UIApplicationShortcutIcon iconWithTemplateImageName:#"img_editProduct"];
UIApplicationShortcutIcon *icon2 = [UIApplicationShortcutIcon iconWithTemplateImageName:#"img_Classifieds"];
UIMutableApplicationShortcutItem *item1 = [[UIMutableApplicationShortcutItem alloc]initWithType:#"com.3dtouchApp.postAnItem" localizedTitle:#"Post an Item" localizedSubtitle:#"Add new product for sale" icon:icon1 userInfo:nil];
UIMutableApplicationShortcutItem *item2 = [[UIMutableApplicationShortcutItem alloc]initWithType:#"com.3dtouchApp.LatestAds" localizedTitle:#"Latest Ads" localizedSubtitle:#"View top recent Ads" icon:icon2 userInfo:nil];
NSArray *items = #[item2, item1];
[UIApplication sharedApplication].shortcutItems = items;
}
#catch (NSException *exception) {
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (self.window.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
{
[self shortcutsWithIcon];
UIApplicationShortcutItem *item = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];
if (item) {
NSLog(#"We've launched from shortcut item: %#", item.localizedTitle);
} else {
NSLog(#"We've launched properly.");
}
if ([item.type isEqualToString:#"com.3dtouchApp.postAnItem"])
{
***//Code for launch your screen***
}
if ([item.type isEqualToString:#"com.3dtouchApp.LatestAds"])
{
***//code for launch your screen***
}
}
return YES;
}
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
if ([shortcutItem.type isEqualToString:#"com.3dtouchApp.LatestAds"])
{
***//Code for launch your screen***
}
if ([shortcutItem.type isEqualToString:#"com.3dtouchApp.postAnItem"])
{
***//Code for launch your screen***
}
}

is it possible to call API through Glance apple watch using NSUserActivity

as apple suggested use Handoff in Glance .
I wants to call web API in Glance Interface , for this I did following things
- (void)awakeWithContext:(id)context
{
[super awakeWithContext:context];
[self CreateUaerActivity];
}
-(void)CreateUaerActivity
{
NSUserActivity *activity = [[NSUserActivity alloc] initWithActivityType:#"com.xxx.xxx.glance"];
activity.title = #"Glance";
activity.delegate=self;
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:kUserLoginWatchKit,kRequestTypeWatchKit, nil];
activity.userInfo = dict;
self.userActivity = activity;
[self.userActivity becomeCurrent];
}
- (void)willActivate
{
[super willActivate];
[NSTimer scheduledTimerWithTimeInterval:120 target:self selector:#selector(doSomething) userInfo:nil repeats:YES];
}
-(void)doSomething
{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:kUserLoginWatchKit,kRequestTypeWatchKit, nil];
[super updateUserActivity:#"com.xxx.xxx.glance" userInfo:dict webpageURL:nil];
}
-(void)handleUserActivity:(NSDictionary *)userInfo
{
//displaying data
}
and in AppDelegate.m file -
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler
{
NSLog(#"Handoff dictionary: %#", userActivity.userInfo);
NSString *requestType = userActivity.userInfo[kRequestTypeWatchKit];
if ([requestType isEqual: kGlanceDataWatchKit])
{
//calling web API to get Data
}
return YES;
}
I found AppDelegate never called continueUserActivity method to return something to Glance interface.
please guide me how to call API through Glance Interface.
I'm not sure if this is what you want, but if you want to call an web Api i suggest yout to do it like this :
in the GlanceInterfaceController :
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:#"getSomething" forKey:#"action"];
[MainInterfaceController openParentApplication:dictionary reply:^(NSDictionary *replyInfo, NSError *error) {
NSLog(#"Reply received by Watch app: %#", replyInfo); // the reply from the appDelegate...
}
in your parent's app Delegate :
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
NSLog(#"Request received by iOS app");
if( [userInfo objectForKey:#"action"] isEqualToString:#"getSomething"] ){
//call you're Web API
//send the reponse to you're glance :
reply(DictResponse);// some Dictionary from your web API...
}
*****EDIT*****
i've been issued the same issue, one easy fix is to begin an background task, from :
fiveminutewatchkit
Here's the way :
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
// Temporary fix, I hope.
// --------------------
__block UIBackgroundTaskIdentifier bogusWorkaroundTask;
bogusWorkaroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bogusWorkaroundTask];
}];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] endBackgroundTask:bogusWorkaroundTask];
});
// --------------------
__block UIBackgroundTaskIdentifier realBackgroundTask;
realBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
reply(nil);
[[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
}];
// Kick off a network request, heavy processing work, etc.
// Return any data you need to, obviously.
reply(nil);
[[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
}
in fact iOS kill your parent's app before you can retrieve data... this (not very clean solution) prevent you're app to be killed... and let you the time to retrieve infos...
******END EDIT******

handleOpenURL not called after linking to Dropbox - iOS

I have started exploring the Dropbox API for an app that I have where I would like the user to be able to back up the database file. The problem I have run into is that after the user links the app with their account (similar to logging in via Facebook) the app doesn't return to the foreground. When I manually go back to the app it is still on the backups screen, but the account has not been linked (as best as I can tell) and the handleOpenUrl app delegate method is not called.
Any ideas? or maybe someone knows a good tutorial for this. The sample Dropbox app works fine, and I'm doing my best to use it as a guide but obviously i've messed something up.
App Delegate:
#import "AppDelegate_iPad.h"
#import <DropboxSDK/DropboxSDK.h>
#interface AppDelegate_iPad () <DBSessionDelegate>
#end
#implementation AppDelegate_iPad
#synthesize window,viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.viewController = [[mainMenuViewController alloc]init];
[window addSubview:viewController.view]; //< this is a main menu viewcontroller for my app
[self.window makeKeyAndVisible];
// Set these variables before launching the app
NSString* appKey = #"XXXX";
NSString* appSecret = #"XXX";
NSString *root = kDBRootAppFolder;
NSString* errorMsg = nil;
if ([appKey rangeOfCharacterFromSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]].location != NSNotFound) {
errorMsg = #"Make sure you set the app key correctly in DBRouletteAppDelegate.m";
} else if ([appSecret rangeOfCharacterFromSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]].location != NSNotFound) {
errorMsg = #"Make sure you set the app secret correctly in DBRouletteAppDelegate.m";
} else if ([root length] == 0) {
errorMsg = #"Set your root to use either App Folder of full Dropbox";
} else {
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"Info" ofType:#"plist"];
NSData *plistData = [NSData dataWithContentsOfFile:plistPath];
NSDictionary *loadedPlist =
[NSPropertyListSerialization
propertyListFromData:plistData mutabilityOption:0 format:NULL errorDescription:NULL];
NSString *scheme = [[[[loadedPlist objectForKey:#"CFBundleURLTypes"] objectAtIndex:0] objectForKey:#"CFBundleURLSchemes"] objectAtIndex:0];
if ([scheme isEqual:#"db-APP_KEY"]) {
errorMsg = #"Set your URL scheme correctly in DBRoulette-Info.plist";
}
}
DBSession* session =
[[DBSession alloc] initWithAppKey:appKey appSecret:appSecret root:root];
session.delegate = self; // DBSessionDelegate methods allow you to handle re-authenticating
[DBSession setSharedSession:session];
[session release];
if (errorMsg != nil) {
[[[[UIAlertView alloc]
initWithTitle:#"Error Configuring Session" message:errorMsg
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil]
autorelease]
show];
}
NSURL *launchURL = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
NSInteger majorVersion =
[[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:#"."] objectAtIndex:0] integerValue];
if (launchURL && majorVersion < 4) {
// Pre-iOS 4.0 won't call application:handleOpenURL; this code is only needed if you support
// iOS versions 3.2 or below
[self application:application handleOpenURL:launchURL];
return NO;
}
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { /// this is never called
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"App linked successfully!");
// At this point you can start making API calls
}
return YES;
}
return NO;
}
#end
From the main Menu, the user pressed a backup button and that opens the following view controller:
#import "BackupManagerViewController.h"
#import <DropboxSDK/DropboxSDK.h>
#import <stdlib.h>
#interface BackupManagerViewController () <DBRestClientDelegate>
//#property (nonatomic, readonly) DBRestClient* restClient;
#end
#implementation BackupManagerViewController
#synthesize itemsArray,delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
//[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
return (orientation != UIDeviceOrientationLandscapeLeft) &&
(orientation != UIDeviceOrientationLandscapeRight);
}
- (IBAction)didPressLink {
if (![[DBSession sharedSession] isLinked]) {
[[DBSession sharedSession] link];
} else {
[[DBSession sharedSession] unlinkAll];
[[[[UIAlertView alloc]
initWithTitle:#"Account Unlinked!" message:#"Your dropbox account has been unlinked"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil]
autorelease]
show];
}
}
-(DBRestClient *)restClient{
if (restClient == nil) {
restClient = [[DBRestClient alloc]initWithSession:[DBSession sharedSession]];
restClient.delegate = self;
}
return restClient;
}
-(IBAction) closeButtonPressed {
[delegate closeBackupManager];
}
#end
Things to check are
Make sure you don't have two applications with same db-APP_KEY
Make sure only one of these is implemented (not both) in your application delegate.
(a)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
(b)
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
Option (b) is deprecated so please go with the option (a) in your new applications
You have entered correct APP_KEY in the URL scheme .
I ran into the same problem, but got it working after deleting the sample app DBRoulette from the simulator. I also deleted my own app and restarted the simulator, but I am not sure if those steps were necessary.
Did you add the drop box URL schema to your app's info.plist?
I believe this problem had to do with running in the simulator. I ran it on a device and it worked fine.

Resources