I am trying to establish voip call through two different apps. Lets assume one is seller and another is customer. Seller app can only call, and customer app can only receive call. I have setup two apps with sinch applicationKey, secret, userID etc. As I want to receive call in customer app, I have generated VOIP certificate in Apple Dev Account for customer app's bundle id. And I have uploaded that certificate(p12) in Sinch Dashboard. I am using Managed Push in customer app.
But I am unable to receive push or calls in customer app.
I tried changing the bundle id of the two apps. When I keep the bundle id same for the two apps, it works like charm.
My question is, How can I make voip calls between two different apps with different bundle ids?
Here is my AppDelegate.m file codes, which works as it should when the bundle id is same:
#import "SINCallKitProvider.h"
#import "CallViewController.h"
#interface AppDelegate () <SINClientDelegate, SINCallClientDelegate, SINManagedPushDelegate>
#property (nonatomic, readwrite, strong) id<SINManagedPush> push;
#property (nonatomic, readwrite, strong) SINCallKitProvider *callKitProvider;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"didFinishLaunchingWithOptions:");
[Sinch setLogCallback:^(SINLogSeverity severity, NSString *area, NSString *message, NSDate *timestamp) {
NSLog(#"[%#] %#", area, message);
}];
self.push = [Sinch managedPushWithAPSEnvironment:SINAPSEnvironmentAutomatic];
self.push.delegate = self;
[self.push setDesiredPushType:SINPushTypeVoIP];
self.callKitProvider = [[SINCallKitProvider alloc] init];
void (^onUserDidLogin)(NSString *) = ^(NSString *userId) {
[self initSinchClientWithUserId:userId];
};
[[NSNotificationCenter defaultCenter]
addObserverForName:#"UserDidLoginNotification"
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
NSString *userId = note.userInfo[#"userId"];
[[NSUserDefaults standardUserDefaults] setObject:userId forKey:#"userId"];
[[NSUserDefaults standardUserDefaults] synchronize];
onUserDidLogin(userId);
}];
[[NSNotificationCenter defaultCenter] addObserverForName:#"UserDidLogoutNotification"
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
_client = nil;
}];
return YES;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
id<SINCall> call = [_callKitProvider currentEstablishedCall];
// If there is one established call, show the callView of the current call when
// the App is brought to foreground. This is mainly to handle the UI transition
// when clicking the App icon on the lockscreen CallKit UI.
if (call) {
UIViewController *top = self.window.rootViewController;
while (top.presentedViewController) {
top = top.presentedViewController;
}
// When entering the application via the App button on the CallKit lockscreen,
// and unlocking the device by PIN code/Touch ID, applicationWillEnterForeground:
// will be invoked twice, and "top" will be CallViewController already after
// the first invocation.
if (![top isMemberOfClass:[CallViewController class]]) {
[top performSegueWithIdentifier:#"callView" sender:call];
}
}
}
#pragma mark -
- (void)initSinchClientWithUserId:(NSString *)userId {
if (!_client) {
_client = [Sinch clientWithApplicationKey:#"<My key>"
applicationSecret:#"<My secret>"
environmentHost:#"clientapi.sinch.com"
userId:userId];
_client.delegate = self;
_client.callClient.delegate = self;
[_client setSupportCalling:YES];
[_client enableManagedPushNotifications];
_callKitProvider.client = _client;
[_client start];
// [_client startListeningOnActiveConnection];
}
}
- (void)handleRemoteNotification:(NSDictionary *)userInfo {
if (!_client) {
NSString *userId = [[NSUserDefaults standardUserDefaults] objectForKey:#"userId"];
if (userId) {
[self initSinchClientWithUserId:userId];
}
}
[self.client relayRemotePushNotification:userInfo];
}
#pragma mark - SINManagedPushDelegate
- (void)managedPush:(id<SINManagedPush>)managedPush
didReceiveIncomingPushWithPayload:(NSDictionary *)payload
forType:(NSString *)pushType {
NSLog(#"didReceiveIncomingPushWithPayload: %#", payload.description);
// Since iOS 13 the application must report an incoming call to CallKit if a
// VoIP push notification was used, and this must be done within the same run
// loop as the push is received (i.e. GCD async dispatch must not be used).
// See https://developer.apple.com/documentation/pushkit/pkpushregistrydelegate/2875784-pushregistry .
[self.callKitProvider didReceivePushWithPayload:payload];
dispatch_async(dispatch_get_main_queue(), ^{
[self handleRemoteNotification:payload];
[self.push didCompleteProcessingPushPayload:payload];
});
}
#pragma mark - SINCallClientDelegate
- (void)client:(id<SINCallClient>)client didReceiveIncomingCall:(id<SINCall>)call {
// Find MainViewController and present CallViewController from it.
UIViewController *top = self.window.rootViewController;
while (top.presentedViewController) {
top = top.presentedViewController;
}
[top performSegueWithIdentifier:#"callView" sender:call];
}
- (void)client:(id<SINClient>)client willReceiveIncomingCall:(id<SINCall>)call {
[self.callKitProvider willReceiveIncomingCall:call];
}
#pragma mark - SINClientDelegate
- (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]);
}
#end
Related
I use Sinch VOIP to make calling between App-To-App in iOS 11.1.2
Work well when the application status is foreground but in background and terminated nothing happened after I open the application console print
Pubnub request SCHEDULED (ID=081E49C2-C30A-4B4B-840C-E6A6051E6F44, URL=https://rebtelsdk.pubnub.com/subscribe/sub-c-c5e52f20-d446-11e3-b488-02ee2ddab7fe/5e1e1309-136a-40d4-935f-2627ebe4e8f2B/0/0, NST-VoIP: NO)
Pubnub request STARTED (ID=081E49C2-C30A-4B4B-840C-E6A6051E6F44)
Pubnub request SUCCESS (ID=081E49C2-C30A-4B4B-840C-E6A6051E6F44):
(
(
),
15117251992031337
)
onPubSubSubscriptionSuccess: userInfo: {
channel = "5e1e1309-136a-40d4-935f-2627ebe4e8f2B";
subscribeSequence = 1;
timetoken = 0;
useVoIPNetworkServiceType = 0;
}
I upload VOIP & APNS certificates to Sinch dashboard and I used SINManagedPush & PushKit My code is
Setup Push Manager & SINClient in didFinishLaunchingWithOptions
self.push = [Sinch managedPushWithAPSEnvironment:SINAPSEnvironmentAutomatic];
self.push.delegate = self;
[self.push setDesiredPushTypeAutomatically];
void (^onUserDidLogin)(NSString *) = ^(NSString *userId) {
[self.push registerUserNotificationSettings];
[self initSinchClientWithUserId:userId];
};
[[NSNotificationCenter defaultCenter]
addObserverForName:#"UserDidLoginNotification"
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
NSString *userId = note.userInfo[#"userId"];
[[NSUserDefaults standardUserDefaults] setObject:userId forKey:#"userId"];
[[NSUserDefaults standardUserDefaults] synchronize];
onUserDidLogin(userId);
}];
- (void)initSinchClientWithUserId:(NSString *)userId {
if (!_client) {
_client = [Sinch clientWithApplicationKey:#"APP-Key"
applicationSecret:#"APP-Secret"
environmentHost:#"sandbox.sinch.com"
userId:userId];
_client.delegate = self;
_client.callClient.delegate = self;
[_client setSupportCalling:YES];
[_client enableManagedPushNotifications];
[_client start];
[_client startListeningOnActiveConnection];
_callKitProvider = [[SINCallKitProvider alloc] initWithClient:_client];
}
}
Get Device Token
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[self.push application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(#"User Info : %#",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
[self.push application:[UIApplication sharedApplication] didReceiveRemoteNotification:notification.request.content.userInfo];
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
NSLog(#"User Info : %#",response.notification.request.content.userInfo);
completionHandler();
[self.push application:[UIApplication sharedApplication] didReceiveRemoteNotification:response.notification.request.content.userInfo];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[self.push application:application didReceiveRemoteNotification:userInfo];
}
PushKit
-(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
{
[_client registerPushNotificationData:credentials.token];
}
-(void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type{
NSLog(#"invalidated");
}
4.Call voipRegistration when SINClient start
- (void)clientDidStart:(id<SINClient>)client {
NSLog(#"Sinch client started successfully (version: %#)", [Sinch version]);
[self voipRegistration];
}
5.Implement SINManagedPushDelegate & SINCallClientDelegate
- (void)client:(id<SINCallClient>)client didReceiveIncomingCall:(id<SINCall>)call {
UIViewController *top = self.window.rootViewController;
while (top.presentedViewController) {
top = top.presentedViewController;
}
[top performSegueWithIdentifier:#"callView" sender:call];
}
- (SINLocalNotification *)client:(id<SINClient>)client localNotificationForIncomingCall:(id<SINCall>)call {
SINLocalNotification *notification = [[SINLocalNotification alloc] init];
NSArray * ansAr = #[#"رد",#"Answer"];
NSArray * MsgAr = #[[NSString stringWithFormat:#"مكالمة لم يرد عليها من %#", [call remoteUserId]],[NSString stringWithFormat:#"Incoming call from %#", [call remoteUserId]]];
notification.alertAction = ansAr[self.languageID];
notification.alertBody = MsgAr[self.languageID];
return notification;
}
- (void)client:(id<SINClient>)client willReceiveIncomingCall:(id<SINCall>)call {
[self.callKitProvider reportNewIncomingCall:call];
}
These is the code , Please help me if I forgot anything.
I checked the credentials.token is not null.
Thank you for your help.
When you setup the Sinch managed push with the code below:
self.push = [Sinch managedPushWithAPSEnvironment:SINAPSEnvironmentAutomatic];
self.push.delegate = self;
[self.push setDesiredPushTypeAutomatically];
The Sinch SDK will automatically do all the PushKit registration for you. So step 3 and 4 in your description is not necessary and should not be there. Part of the code in step 2 is not needed as well. Please take a look at the Sinch CallKit sample app from the SDK download package, and refer to the implementation of that App.
Below is a demo video made with the 3.12.4 Sinch SDK CallKit Sample App without any tweak, the device used in the demo is an iPhone7 running iOS 11, it gets the incoming call in background, killed and lockscreen mode:
Sinch CallKit Sample App Demo Video
Also, note that callKit only works with VoIP push, have you uploaded the right type of push certificate to Sinch Portal?
When you force kill an app apple wont wake the app for VoIP push, if you just have in background or reboot the phone apple will wake it up. Annoying, but that's apple
I used Pushbots to configure push notifications for my app. After I get the notification, I am able to put it into a UITableview. However the notification only appears after the user restarts the app. Is there a way to immediately add the notification text after the user gets it, or when the user clicks the notification?
In my AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Pushbots sharedInstanceWithAppId:#"--myAppid--"];
[[Pushbots sharedInstance] receivedPush:launchOptions];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// This method will be called everytime you open the app
// Register the deviceToken on Pushbots
[[Pushbots sharedInstance] registerOnPushbots:deviceToken];
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(#"Notification Registration Error %#", [error userInfo]);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//Handle notification when the user click it while app is running in background or foreground.
[[Pushbots sharedInstance] receivedPush:userInfo];
//NSLog(#"UserInfo: %#", userInfo);
NSString *msg = [userInfo valueForKey:#"aps"];
NSString *alertMsg = [msg valueForKey:#"alert"];
//NSLog(#"Push Notification:%#",alertMsg);
[[NSUserDefaults standardUserDefaults]setObject:alertMsg forKey:#"ReceivedNotifications"];
NSLog(#"Alert: %#", alertMsg);
}
In my ViewController.m:
#import "ViewController.h"
#interface ViewController () <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *notifTableView;
#end
#implementation ViewController
{
NSMutableArray *notif;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.notifTableView.dataSource = self;
self.notifTableView.delegate = self;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *checkAlert = [[NSString alloc] init];
checkAlert = [defaults stringForKey:#"ReceivedNotifications"];
NSLog(#"Alert Message: %#", checkAlert);
notif = [NSMutableArray arrayWithObjects:checkAlert, nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [notif count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
cell.textLabel.text = [notif objectAtIndex:indexPath.row];
return cell;
}
In your ViewController viewDidLoad method start listen to a NSNotification as below,
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveNotification:)
name:#"TestNotification"
object:nil];
Add this receiveNotification to your ViewController as well. Inside this if condition you can reload the TableView.
- (void) receiveNotification:(NSNotification *) notification
{
// [notification name] should always be #"TestNotification"
// unless you use this method for observation of other notifications
// as well.
if ([[notification name] isEqualToString:#"TestNotification"])
NSLog (#"Successfully received the test notification!");
}
Don't forget to remove the notification when you dealloc the ViewController,
[[NSNotificationCenter defaultCenter] removeObserver:self];
Then from your AppDelegate once you receive a notification, post a Notification to TestNotification name
[[NSNotificationCenter defaultCenter]
postNotificationName:#"TestNotification"
object:nil]; //You can set object as nil or send the object you want to get from the ViewController
try to use NSNoticationCenter same as DilumN said in his answer , when you receive the notification then reload the tableview in that method.
Currently, a session does not seem to be retained when an MQTTClient object is reinitialized with the same client id and then connected to the broker.
Consider the following code:
//Just a tiny wrapper around MQTTClient for custom methods
#property (nonatomic, strong) RAMQTTClient *client;
#implementation MQTTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//The selector gets called whenever a new message is received
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didReceiveMessage:) name:#"didReceiveMessage" object:nil];
//Initialises an MQTT client with QOS=1 and cleanSession=NO
_client = [[RAMQTTClient alloc]initWithId:#"client-1"];
}
-(void)didReceiveMessage:(NSNotification *)notification {
NSString *data = (NSString *)notification.object;
NSLog(#"Received: %#", data);
}
// Use a switch action to subscribe and disconnect
- (IBAction)switchUpdated:(id)sender {
BOOL on = [sender isOn];
if (on) {
[_client listenToTopic:#"a~1"];
} else {
[_client disconnect];
}
}
#end
As long as the _client object is not destroyed, disconnecting and reconnecting does retrieve the offline messages sent in that interval. However if the client gets reinitialised and then starts to listen, I don't get any of the offline messages.
The following is the implementation of RAMQTTClient:
typedef void (^ConnectionCompletionHandler)(MQTTConnectionReturnCode code);
#interface RAMQTTClient()
#property (strong, nonatomic) MQTTClient *client;
#property (nonatomic) MQTTConnectionReturnCode connectionCode;
#end
#implementation RAMQTTClient
-(instancetype)initWithId:(NSString*)id {
if (self = [super init]) {
_client = [[MQTTClient alloc]initWithClientId:id cleanSession:NO];
}
return self;
}
-(BOOL)isRunning {
return _client.connected;
}
-(NSString *)id {
return _client.clientID;
}
-(void)connectWithCompletionHandler:(ConnectionCompletionHandler)handler {
if (!_client.connected) {
[_client connectToHost:#"localhost" completionHandler:handler];
}
}
-(void)listenToTopic:(NSString *)topic {
ConnectionCompletionHandler completionHandler = ^(MQTTConnectionReturnCode code) {
NSLog(#"RAMQTTClient: %# connected", _client.clientID);
_connectionCode = code;
if (code == ConnectionAccepted) {
[_client subscribe:topic withQos:AtLeastOnce completionHandler:^(NSArray *grantedQos) {
NSLog(#"RAMQTTClient: Listening to %#", topic);
[_client setMessageHandler:^(MQTTMessage *message) {
NSLog(#"Message => %#",message.payloadString);
[[NSNotificationCenter defaultCenter]postNotificationName:#"didReceiveMessage"
object:message.payloadString];
}];
}];
}
};
[self connectWithCompletionHandler:completionHandler];
}
-(void)disconnect {
if (_client.connected) {
[_client disconnectWithCompletionHandler:^(NSUInteger code) {
NSLog(#"RAMQTTClient: %# Disconnected with code %u", _client.clientID, code);
}];
}
}
#end
Have any of you faced this sort of issue before? Is there a workaround for this?
For those interested, I've figured it out. The problem was setting a message handler after subscribing to a topic. Since offline messages arrive instantly when you subscribe, the client is unable to wait or set the message handler before receiving them. As a result, even though the messages arrive, they aren't sent to the handler. Setting the message handler before subscribing to the channel solves this.
[_client setMessageHandler:^(MQTTMessage *message) {
NSLog(#"Message => %#",message.payloadString);
[[NSNotificationCenter defaultCenter]postNotificationName:#"didReceiveMessage"
object:message.payloadString];
}];
[_client subscribe:topic withQos:AtLeastOnce completionHandler:^(NSArray *grantedQos) {
NSLog(#"RAMQTTClient: Listening to %#", topic);
}];
I'm using Mutipeer Connectivity to make a chat app. At first, everything worked well and MCSession can connect with each other. But when user tap home button and then tap app icon, the apps disconnect with each other and often can't reconnect. But sometimes it can reconnect. The success is random.
- (void)viewDidLoad
{
[super viewDidLoad];
...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(DidBecomeActive:)
name: UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didEnterBackground:)
name: UIApplicationDidEnterBackgroundNotification object:nil];
NSString *displayname=[[NSUUID UUID] UUIDString];
_MyPeerID=[[MCPeerID alloc] initWithDisplayName:displayname];
}
- (void)DidBecomeActive:(NSNotification *)notification
{
if (notFirstLaunch==YES) {
NSLog(#"DidBecomeActive");
NSString *displayname=[[NSUUID UUID] UUIDString];
_MyPeerID=[[MCPeerID alloc] initWithDisplayName:displayname];
[self createSession];
[self createAdvertiser];
[self beginBrowsing];
}
notFirstLaunch=YES;
}
- (void)didEnterBackground:(NSNotification *)notification
{
NSLog(#"didEnterBackground");
[_MySession disconnect];
_MySession=nil;
_MyBrowser=nil;
_MyAdver=nil;
}
- (void)createSession
{
_MySession=[[MCSession alloc] initWithPeer:_MyPeerID];
_MySession.delegate=self;
}
- (void)createAdvertiser
{
_MyAdver=[[MCNearbyServiceAdvertiser alloc] initWithPeer:_MyPeerID discoveryInfo:nil serviceType:MyServiceType];
_MyAdver.delegate=self;
[_MyAdver startAdvertisingPeer];
}
- (void)beginBrowsing {
_MyBrowser=[[MCNearbyServiceBrowser alloc] initWithPeer:_MyPeerID serviceType:MyServiceType];
_MyBrowser.delegate=self;
[_MyBrowser startBrowsingForPeers];
}
Judging by the code you've posted, nothing reconnects because in didEnterBackground you disconnect from the session and destroy the session, browser and advertiser. In DidBecomeActive you have a guard (notFirstLaunch) that means that the session and advertiser are only created the first time you become active, and NOT after you become active when you come back from being in the background.
I'm trying to integrate BOX V2 IOS SDk on my ios project , the integration is fine, but when I try to login , and after I enter my username and password and granted the access , I get a white screen , and the boxAPIAuthenticationDidSucceed method is not called , her is my code
the connexion Method :
-(void) connectToBox {
[BoxSDK sharedSDK].OAuth2Session.clientID = #"my-client-id";
[BoxSDK sharedSDK].OAuth2Session.clientSecret = #"my-client-secret";
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(boxAPIAuthenticationDidSucceed:)
name:BoxOAuth2SessionDidBecomeAuthenticatedNotification
object:[BoxSDK sharedSDK].OAuth2Session];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(boxAPIAuthenticationDidFail:)
name:BoxOAuth2SessionDidReceiveAuthenticationErrorNotification
object:[BoxSDK sharedSDK].OAuth2Session];
self.LoginCotroller = [[BoxAuthorizationViewController alloc] initWithAuthorizationURL:authorizationURL redirectURI:redirectURI];
[self presentViewController:self.LoginCotroller animated:YES completion:nil];
}
and I implement the two methods :
- (void)boxAPIAuthenticationDidSucceed:(NSNotification *)notification;
- (void)boxAPIAuthenticationDidFail:(NSNotification *)notification;
and the notifications methods :
#pragma mark - Handle OAuth2 session notifications
- (void)boxAPIAuthenticationDidSucceed:(NSNotification *)notification
{
BoxOAuth2Session *session = (BoxOAuth2Session *) notification.object;
NSLog(#"Received OAuth2 successfully authenticated notification");
NSLog(#"Access token (%#) expires at %#", session.accessToken, session.accessTokenExpiration);
NSLog(#"Refresh token (%#)", session.refreshToken);
dispatch_sync(dispatch_get_main_queue(), ^{
[self.LoginCotroller dismissViewControllerAnimated:YES completion:nil];
});
}
- (void)boxAPIAuthenticationDidFail:(NSNotification *)notification
{
NSLog(#"Received OAuth2 failed authenticated notification");
NSString *oauth2Error = [[notification userInfo] valueForKey:BoxOAuth2AuthenticationErrorKey];
NSLog(#"Authentication error (%#)", oauth2Error);
dispatch_sync(dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
});
}
I dont know what wrong with my code.So if any one can help.Thanks
I'd suggest adding your controller as an observer for BoxOAuth2SessionDidRefreshTokensNotification as well to call boxAPIAuthenticationDidSucceed: method. BoxOAuth2SessionDidRefreshTokensNotification is posted when a new access-token is created/refresed.