Reputation: 3767
I have seen a lot of different posts about how to solve this problem, but I have had no luck. I have tried the heartbeat solution, and it does nothing. I know that my keychain is storing my refresh token, but it is not serving any use.
Steps:
EDIT: First I get a 20000 error. It seems my authentication tokens are not refreshing.
Error Domain=com.box.sdk.errordomain Code=20002 "The operation couldn’t be completed. (com.box.sdk.errordomain error 20002.)"
I am using this code to refresh my access tokens (I think it is supposed to)
if (storedRefreshToken)
{
[BoxSDK sharedSDK].OAuth2Session.refreshToken = storedRefreshToken;
}
I feel like I am missing something here also.
I need my user to stay logged in for the allowed 14 days. How can I get the app login state to survive app restarts?
I am using the latest V2 SDK.
EDIT:
I have tried everything, from refreshing the refreshtoken in the keychain on each ViewController to referencing the AppDelegate. I can't get it to stay logged in and just keep getting the 20002 error when I start the app again (not resume, but cold start). I don't want to use the Box filepicker, but I want to make my own tableview. Any other ideas out there?
AppDelegate:
in didFinishLaunching:
[BoxSDK sharedSDK].OAuth2Session.clientID = @"XXXXXXXXXX";
[BoxSDK sharedSDK].OAuth2Session.clientSecret = @"XXXXXXX";
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(boxAPITokensDidRefresh:) name:BoxOAuth2SessionDidBecomeAuthenticatedNotification object:[BoxSDK sharedSDK].OAuth2Session];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setRefreshTokenInKeychain:) name:BoxOAuth2SessionDidRefreshTokensNotification object:[BoxSDK sharedSDK].OAuth2Session];
// set up stored OAuth2 refresh token
_keychain = [[KeychainItemWrapper alloc] initWithIdentifier:REFRESH_TOKEN_KEY accessGroup:nil];
id storedRefreshToken = [_keychain objectForKey:(__bridge id)kSecValueData];
if (storedRefreshToken)
{
[BoxSDK sharedSDK].OAuth2Session.refreshToken = storedRefreshToken;
}
listener methods
- (void)boxAPITokensDidRefresh:(NSNotification *)notification
{
BoxOAuth2Session *OAuth2Session = (BoxOAuth2Session *) notification.object;
[self setRefreshTokenInKeychain:OAuth2Session.refreshToken];
_isBox = YES;
[self removeBoxLoginViewController];
}
- (void)setRefreshTokenInKeychain:(NSString *)refreshToken
{
[_keychain setObject:@"MyApp" forKey: (__bridge id)kSecAttrService];
[_keychain setObject:refreshToken forKey:(__bridge id)kSecValueData];
NSLog(@"refreshToken: %@", refreshToken);
}
Main ViewController: ViewDidLoad
[[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];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(boxAPIAuthenticationRefreshToken:) name:BoxOAuth2SessionDidReceiveRefreshErrorNotification object:[BoxSDK sharedSDK].OAuth2Session];
[self boxAPIHeartbeat];
Heartbeat:
- (void)boxAPIHeartbeat
{
[[BoxSDK sharedSDK].foldersManager folderInfoWithID:@"0" requestBuilder:nil success:nil failure:nil];
}
ListenerMethods after hearbeat:
- (void)boxAPIAuthenticationDidSucceed:(NSNotification *)notification
{
NSLog(@"Received OAuth2 successfully authenticated notification");
BoxOAuth2Session *session = (BoxOAuth2Session *) [notification object];
NSLog(@"Access token (%@) expires at %@", session.accessToken, session.accessTokenExpiration);
NSLog(@"Refresh token (%@)", session.refreshToken);
//[self.tableView reloadData];
}
- (void)boxAPIAuthenticationDidFail:(NSNotification *)notification
{
NSLog(@"Received OAuth2 failed authenticated notification");
NSString *oauth2Error = [[notification userInfo] valueForKey:BoxOAuth2AuthenticationErrorKey];
NSLog(@"Authentication error (%@)", oauth2Error);
//[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)boxAPIAuthenticationRefreshToken:(NSNotification *)notification
{
BoxOAuth2Session *OAuth2Session = (BoxOAuth2Session *) notification.object;
[self setRefreshTokenInKeychain:OAuth2Session.refreshToken];
NSLog(@"REFRESH TOKEN: %@", OAuth2Session.refreshToken);
}
//trying this out????
- (void)setRefreshTokenInKeychain:(NSString *)refreshToken
{
[_keychain setObject:@"MyApp" forKey: (__bridge id)kSecAttrService];
[_keychain setObject:refreshToken forKey:(__bridge id)kSecValueData];
NSLog(@"refreshToken: %@", refreshToken);
}
I can't use the Box SDK if I can't get this figured out this weekend. I would think Box would want their SDK to be used by developers, but the documentation is so poor. What am I missing? I just want the app to stay logged in through cold starts!
Upvotes: 1
Views: 889
Reputation: 3767
It turns out, that the issue was with the ARC version of Keychain. I noticed this when I started placing NSLogs all over the place and noticed that the refreshToken getting returned at app launch, was not the refreshToken that was getting encoded into the Keychain. I replaced the ARC Keychain files with the ones from the sample app and put the ARC flag in, and it is working perfectly.
Upvotes: 1