加载用户文件的所有路径时 Dropbox 错误 400 invalid_request

Dropbox error 400 invalid_request when loading all paths of the users files

我在用户登录后尝试从应用程序文件夹中检索用户的完整文件名列表时收到错误 400。

我正在使用本教程来设置 Dropbox SDK: https://www.dropbox.com/developers-v1/core/start/ios

但稍微改变了方法,因为并非所有操作都发生在我的应用程序委托 .m 文件中。

此外,我在第一次 运行 应用程序后遇到了错误,尽管我是按照教程中的那样操作的,但经过快速搜索后,我发现我必须在我的 Info.plis 用于 运行 的所有内容: LSApplicationQueriesSchemes dbapi-2

这样做之后,我能够成功地向 Dropbox 进行身份验证,然后我将请求发送到共享会话自定义 class,它包含我的其余 Dropbox 功能并尝试获取列表应用程序文件夹中的文件,然后出现下一个错误:

App linked successfully!
[WARNING] DropboxSDK: error making request to /1/metadata/sandbox - (400) invalid_request
 Error loading metadata: Error Domain=dropbox.com Code=400 "(null)" UserInfo={error_description=No auth function available for given request, path=/, error=invalid_request}

如果我将相同的代码放入同一 class 的 viewWillAppear 或 viewDidLoad 中,则出现此错误后,代码将被执行,它 returns 和空字典 表示我的应用程序文件夹中没有照片,我可以继续上传文件。

我的问题是: 为什么我必须重新启动应用程序才能使相同的调用起作用,为什么它从一开始就不起作用?

现在进行我的设置: 1. 当我在我选择的 dropbox 应用平台上创建应用时: - API : Dropbox API 不是 dropbox for business api - 权限:APP 文件夹不是完整的 Dropbox 2. 在 info.plis 文件中,我添加了下一个值:

 <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>dbapi-2</string>
    </array>

并且:

现在在我的应用程序中 delegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

.........
[self initDropbox];
return YES;
}

- (void)initDropbox{

    DBSession *dbSession = [[DBSession alloc]
                            initWithAppKey:@"appKey"
                            appSecret:@"appSecret"
                            root:kDBRootAppFolder]; 
    [DBSession setSharedSession:dbSession];

}

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
  sourceApplication:(NSString *)source
         annotation:(id)annotation {
    if ([[DBSession sharedSession] handleOpenURL:url]) {
        if ([[DBSession sharedSession] isLinked]) {
            NSLog(@"App linked successfully!");
            // At this point you can start making API calls
            [[NSNotificationCenter defaultCenter] postNotificationName:@"applicationDidLinkWithDropbox"
                                                                object:self];

        }
        return YES;
    }
    // Add whatever other url handling code your app requires here
    return NO;
}

在我的视图控制器中我有:

- (void)viewWillAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(dropBoxDidLink:)
                                                 name:@"applicationDidLinkWithDropbox"
                                               object:nil];
//method that gets called after authentication or when the screen is displayed 
//the methods is called only is it if not running already, I check if it is running with the isBussy bool 

    DropBoxSuport *managedObj = [DropBoxSuport sharedInstance];
    BOOL isBussy = managedObj.isUploadingImage;
    if ([managedObj isAuthenticated] && !isBussy) {
        managedObj.isSingleUpload = NO;
        [managedObj startDropboxBackup];
    }

}
- (IBAction)didTappedDropboxButton:(id)sender {
if (![[DBSession sharedSession] isLinked]) {
            [[DBSession sharedSession] linkFromController:self];
        }else{
            [[DBSession sharedSession] unlinkAll];
            dropDownView.firstCellSwitch.on = NO;
        }
}

- (void) dropBoxDidLink:(NSNotification *)notification {
    if ([[notification name] isEqualToString:@"applicationDidLinkWithDropbox"]) {

        dropDownView.firstCellSwitch.on = YES;
        dropDownView.firstCellSwitch.userInteractionEnabled = NO;

        DropBoxSuport *managedObj = [DropBoxSuport sharedInstance];
        BOOL isBussy = managedObj.isUploadingImage;
        if ([managedObj isAuthenticated] && !isBussy) {
            managedObj.isSingleUpload = NO;
            [managedObj startDropboxBackup];
        }
    }
}

在我的习惯中 class(DropBoxSuport.m):

+(instancetype) sharedInstance {
    static dispatch_once_t pred;
    static id shared = nil;
    dispatch_once(&pred, ^{
        shared = [[super alloc] initUniqueInstance];
        [shared initializeRestClient];
    });
    return shared;
}

-(instancetype) initUniqueInstance {
    return [super init];
}

- (void)initializeRestClient{

    restClient = [[DBRestClient alloc] initWithSession:[DBSession sharedSession]];
    restClient.delegate = self;
    context = [self appDelegate].managedObjectContext;

}

- (void)startDropboxBackup{
    if (!isUploadingImage && [self appDelegate].checkForNetwork && [self isAuthenticated]) {
        isUploadingImage = YES;
         [restClient loadMetadata:@"/"];
    }
}

#pragma mark - dropbox delegate get file names
- (void)restClient:(DBRestClient *)client
    loadedMetadata:(DBMetadata *)metadata {

    NSMutableArray *tempArray = [[NSMutableArray alloc] init];
    if (metadata.isDirectory) {
        NSLog(@"Folder '%@' contains:", metadata.path);
        for (DBMetadata *file in metadata.contents) {
            if (file.filename) {
                [tempArray addObject:file.filename];
            }
        }
    }

        NSArray *localStoredImages = [[NSArray alloc] initWithArray:[self loadAllCoreDataImagePaths]];
        NSArray *dropboxStoredImages = [[NSArray alloc] initWithArray:tempArray];

        differenceArray = [self getDifferenceBetweenArray:localStoredImages andSecondArray:dropboxStoredImages];
        if (differenceArray && differenceArray.count > 0) {
            [self startDropboxUpload];
        }else{
            isUploadingImage = NO;
            errorCount = 0;
            currentImageUploaded = 0;
        }





}

- (void)restClient:(DBRestClient *)client
loadMetadataFailedWithError:(NSError *)error {
    NSLog(@"Error loading metadata: %@", error);
    isUploadingImage = NO;
    errorCount = 0;
    currentImageUploaded = 0;
}

这就是我的代码以及我的使用方式,但令我遗憾的是,代码仅在用户首次进行身份验证并且我尝试获取文件夹名称时才会出现。稍后还尝试在不重新启动应用程序的情况下获取文件夹,但发生了同样的错误。但是,如果我重新启动应用程序,一切正常。

非常感谢任何帮助

相信这是一个时间问题。一旦 sharedSession 获得授权,您需要初始化一个新的 DBRestClient

尝试添加一些日志记录以查看相对于链接后更新的 sharedSession 何时调用 sharedInstance

我遇到了和这个问题一样的问题,我是这样解决的:

if (![[DBSession sharedSession] isLinked]) {
    [[DBSession sharedSession] linkFromController:self];
}
self.restClient = [[DBRestClient alloc] initWithSession:[DBSession sharedSession]];
self.restClient.delegate = self;

正如smarx所说,这是时间问题。