1

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:

  1. Start app
  2. Go to load directory (root in this case)
  3. Get this error:

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.)"

  1. Go through Box login process again.
  2. Reload tableview
  3. Works.

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!

Siriss
  • 3,737
  • 4
  • 32
  • 65
  • you can also try logging out of the box account. delete the application and re-download it. Then once its downloaded log back into your account. Then under the settings in scanner pro or your app your using go to your settings and synch it with box. After that it should work on top of the following answers. This has worked for me including the answers above. – Lamar D Howard Jul 30 '18 at 19:55

1 Answers1

1

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.

Siriss
  • 3,737
  • 4
  • 32
  • 65
  • Thanks for letting us know the root cause of the issue. We are having the exact same issue; random 20002 errors during Box operations. Can you elaborate a bit more on how you replaced the ARC Keychain files? Do you mean you don't rely on Box's Keychain classes and replaced with your own version? Any details here would be great. – Guven Mar 02 '16 at 09:40
  • I had a ARC compatible version of Keychain. The original is included with the Box SDK, and is not ARC compatible. I replaced the ARC compatible version with the Keychain that came with the Box SDK and it worked. – Siriss Mar 02 '16 at 16:15