Giter Site home page Giter Site logo

timonus / tjdropbox Goto Github PK

View Code? Open in Web Editor NEW
62.0 8.0 11.0 268 KB

A Dropbox v2 client library written in Objective-C

License: BSD 3-Clause "New" or "Revised" License

Objective-C 99.26% Ruby 0.74%
dropbox dropbox-api dropbox-sdk dropbox-client dropbox-v2 objective-c

tjdropbox's Introduction

TJDropbox

TJDropbox is a Dropbox v2 client library written in Objective-C. When Dropbox originally announced their v2 API they included only a Swift client library, and at the time I wrote TJDropbox as an Objective-C alternative to it to migrate my app Close-up to Dropbox v2. Since then, Dropbox has released an Objective-C v2 SDK. If you’re migrating away from Dropbox’s v1 SDK to v2 and are considering alternatives to Dropbox’s first party solution, TJDropbox is a pretty well featured replacement with no dependencies and very few source files.

Installation

You can use TJDropbox by adding all the source files from the TJDropbox/ directory to your project, or with CocoaPods.

Authentication with TJDropbox is pretty flexible. The simplest way to do it would be to use the provided TJDropboxAuthenticator class.

- (void)authenticate
{
    [TJDropboxAuthenticator authenticateWithClientIdentifier:/*Dropbox client identifier*/
                                         options:/*Options for auth*/
                                                  completion:^(TJDropboxCredential *credential) {
        if (credential) {
            // Auth succeeded, store credential.
        } else {
            // Auth did not succeed.
        }
    }];
}

Be sure to call +tryHandleAuthenticationCallbackWithURL: from your app delegate's -application:openURL:options: method for this to work. TJDropboxAuthenticator attempts auth using the following methods in order of preference.

  1. The Dropbox app (bypassed if bypassNativeAuth is YES in options)
  2. ASWebAuthenticationSession in iOS 12+.
  3. SFAuthenticationSession in iOS 11+.
  4. Auth in Safari.app

That being said, you can also authenticate manually using the utility methods TJDropbox provides. Advanced auth is detailed here.

TJDropbox doesn't store the credentials, that's up to you.

Provided Request Types

Once authenticated, TJDropbox is capable of doing the following things

  • Listing the contents of a folder
  • Downloading files
  • Uploading files
  • Saving files from URLs
  • Moving files (thanks @horseshoe7)
  • Deleting files
  • Getting info about files (thanks @horseshoe7)
  • Getting shareable links to files
  • Getting a user's total space and available space (thanks @onfoot)
  • Creating folders (thanks @blach)

The methods for these are all listed in TJDropbox.h.

Custom Requests

Though TJDropbox only supports a few types of requests for now, internally it has formatters for any Dropbox API request you'd like and handlers for parsing results. Most notably:

  • +apiRequestWithPath:accessToken:parameters: formats RPC requests to the api.dropboxapi.com host.
  • +performAPIRequest:withCompletion: can be used to execute an RPC request.
  • +contentRequestWithPath:accessToken:parameters: formats content requests to the content.dropboxapi.com host.
  • +resultDataForContentRequestResponse: can be used to extract the result API information from a content request.
  • +processResultJSONData:response:error:parsedResult: can be used to process the results from either an RPC or content request.

All the externally exposed methods in TJDropbox are built on top of these utilities, and they can be used to add new functionality to TJDropbox. Requests and pull requests are very welcome!

Architecture notes

  • I wanted to give people who use this library control, which is why auth is largely up to you (though you can use TJDropboxAuthenticationViewController) and storing of tokens is up to you. I don't want to tell you how to manage that stuff, your app may have its own special needs.
  • At the moment, callbacks from TJDropbox methods will come back on threads other than the main thread. That means you'll need to dispatch back to the main thread sometimes, beware!
  • I believe in using boring tech. This is, after all, an Objective-C port of something that there's a Swift version of. There are no external dependencies or craziness, it's just built on top of foundation classes and has little magic to it. I'd prefer to keep it simple.
  • TJDropbox supports iOS 8 and above. It could be modified to support iOS 7 and above, for now the use of NSURLQueryItem is the only thing I think is blocking that.

Todo

  • Better sample project
  • More documentation
  • Carthage support
  • Tests

Apps using TJDropbox

tjdropbox's People

Contributors

blach avatar horseshoe7 avatar readmecritic avatar timonus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tjdropbox's Issues

not support ipv6?

iPad running iOS 9.3.2 and iPhone running iOS 9.3.2 on both Wi-Fi and cellular networks

IPv6 network, an error was shown when we attempted to sign in with Dropbox.

“The operation couldn't be completed. (TJDropboxErrorDomain error 0.) ”

Chinese support for a problem 2

Correctly download files contain the Chinese characters

However

Access to get_temporary_link still have errors

I add:

  • (Void) getTemporaryLink: (NSString * const) path accessToken: (NSString * const) accessToken completion: (void (^ const) (NSDictionary * _Nullable parsedResponse, NSError * _Nullable error)) completion
    {
        NSURLRequest * const request = [self apiRequestWithPath:@"/2/ files/get_temporary_link" accessToken: accessToken parameters: @ {@ "Path": [self asciiEncodeString: path] }];
        [Self performAPIRequest: request withCompletion: completion];
    }

I visited a Chinese called "灯火.mp3" file

Correctly taken to "link" = "https://dl.dropboxusercontent.com/apitl/1/xxx" information.
But https://dl.dropboxusercontent.com/apitl/1/xxx access error Dropbox tips http errorCode 500 error.

The "灯火 .mp3" renamed "cc.mp3" again to get Temporary Link made "link" = "https://dl.dropboxusercontent.com/apitl/1/xxx" information and https: //dl.dropboxusercontent. com/apitl/1/xxx correct data download.

Help, thank you.

get_space_usage parameters

I'm about to use TJDropbox for my app and one of the things I will need is ability to retrieve the amount of free space on user's Dropbox. I implemented the get_space_usage API call, although not without additional changes.

Methods for creating request parameters serialize a nil parameter dictionary as an empty POST body, which is probably not valid JSON content, because by the documentation, get_space_usage requires a "null" value, which definitely is. I could pass an [NSNull null] parameter, but request methods in the library accept a <NSString *, NSString *> dictionary.

So, we could either change the [TJDropbox parameterStringForParameters] method to pass "null" in case of a nil dictionary (which I did), or change all request methods to accept an id parameter and let NSJSONSerialization serialize anything (which I could do, but don't know if such change has any chance of being accepted for a PR).

What do you think?

Chinese support for a problem

    NSString* path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Dropbox 使用入门.pdf"];
    NSLog(@"%@", path);
    [TJDropbox downloadFileAtPath:@"Dropbox 使用入门.pdf" toPath:path accessToken:self.accessToken completion:^(NSDictionary *_Nullable parsedResponse, NSError *_Nullable error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
                NSLog(@"%@ ", [error localizedDescription]);

// self.outputTextView.text = [error description];
} else {
NSLog(@"OK ");
}
});
}];

[TJDropbox downloadFileAtPath:@"Dropbox 使用入门.pdf"

or

[TJDropbox downloadFileAtPath:@"/Dropbox 使用入门.pdf"

All wrong

The operation couldn’t be completed. (TJDropboxErrorDomain error 0.)

Write `TJDropboxAuthenticator` class that wraps various complicated auth methods.

Current ways you can auth in order of preference are

  • Dropbox app
  • ASWebAuthenticationSession
  • SFAuthenticationSession
  • SFSafariViewController
  • Safari app
  • TJDropboxAuthViewController (should be considered deprecated as it relies on UIWebView.

Would be nice if there wasn't as much manual work you had to do to make these all "just work" correctly.

Support multiple windows in auth

Should expose ASWebAuthenticationPresentationContextProviding to clients of TJDropboxAuthentication rather than forcing it to be the key window.

Build warnings with XCode 13.0

Building with XCode 13.0 results in a number of warnings.

  • 'UIWebView' is deprecated: first deprecated in iOS 12.0 - No longer supported; please adopt WKWebView.
  • Object of type 'NSDictionary *' is not compatible with dictionary value type 'NSString *'
  • Object of type 'NSNumber *' is not compatible with dictionary value type 'NSString *'
  • Object of type 'NSMutableDictionary *' is not compatible with dictionary value type 'NSString *'

These are just warnings, so everything seems to work just fine, but it'd be really nice to have a clean build :-)

TjDropox-Compiler-warnings

Dropbox requests fail with non-ascii encoded paths. (i.e. unicode characters)

I had a user with dropbox files containing the cyrillic alphabet. (i.e. "/Океан Эльзи - Без бою.txt")

This would fail using the TJDropbox code out of the box. I found a way to ascii-escape these (well, I also see you have a asciiEncodedString: method), but perhaps these should be on every method that has path as an argument? The out-of-the-box code for parameterString... will not ascii-encode these.

I'm wondering what you'd like to do. You know your code better than I do, so I thought I'd consult first before implementing a definitive fix. I made it work for my app, but it would be nice to get a universal solution in there...

Client ID?

I have an app using dropbox APIv1 right now. I login using app_key and app_secret. Where do I get client ID and what redirect URL do I use in an iOS9 app. I was trying to check out your sample project but without above it won't run.

Warnings in Xcode 9 ...

Hi...
Many thanks for your excellent tool.....
really it's a fantastic job.
I would like to propose one thing only....
Can you include a better example using all of the possibilities?
Also, with Xcode9 I got some strange warnings like

"Object of type 'NSDictionary *' is not compatible with dictionary value type 'NSString *"

can you take a look please?

Thank you very much waiting a response from you!

George Gerardis

Audit was again rejected

MBProgressHUD* hud = [MBProgressHUD HUDForView:self.navigationController.view];
if (error) {

    NSString* errortext = [error localizedDescription];

    if (error.domain && error.domain == TJDropboxErrorDomain) {

        NSString* errorString = error.userInfo [TJDropboxErrorUserInfoKeyErrorString];
        if (errorString) {
            errortext = [errortext stringByAppendingString:@"\n"];
            errortext = [errortext stringByAppendingString:errorString];
        }

        NSDictionary* dropboxError = error.userInfo [TJDropboxErrorUserInfoKeyDropboxError];
        if (dropboxError && [dropboxError isKindOfClass:[NSDictionary class]]) {
            errortext = [errortext stringByAppendingString:@"\n"];
            for (NSString* key in [dropboxError allKeys]) {
                NSString* value = dropboxError[key];
                if ([value isKindOfClass:[NSString class]]) {
                    errortext = [errortext stringByAppendingString:key];
                    errortext = [errortext stringByAppendingString:@"="];
                    errortext = [errortext stringByAppendingString:value];
                    errortext = [errortext stringByAppendingString:@"_"];
                }
            }
        }
    }

    [hud.button setTitle:@"" forState:UIControlStateNormal];
    [hud.button removeTarget:self action:@selector(hudCloseAndPop) forControlEvents:UIControlEventTouchUpInside];
    hud.mode = MBProgressHUDModeText;
    hud.label.text = errortext;
    hud.label.numberOfLines = NSIntegerMax;
    [hud hideAnimated:YES afterDelay:2.0f];
} else {
    [hud hideAnimated:YES];
}

temp czfvlbau

No more detailed error information

Support refresh tokens when using app auth

Hello Tim,

thanks a lot for your efforts in adding support for the new short lived tokens and refresh tokens.

It seems however, that TJDropbox's authentication using the iOS Dropbox app doesn't support refresh tokens yet.

I compared what TJDropbox is doing with what the official Dropbox Objective-C SDK is doing, and could enable refresh tokens using TJDropbox and app auth using two simple modifications.

This is an example request from TJDropbox:

dbapi-2://1/connect?k=9gg2zssmv7XXXXX&s=&state=oauth2code:6Y4vUgu9rIRJbx890ry3mwp2ryhwP0u0FOsaZmMrnx8:S256:&extra_query_params=code_challenge%3D6Y4vUgu9rIRJbx890ry3mwp2ryhwP0u0FOsaZmMrnx8%26code_challenge_method%3DS256%26response_type%3Dcode

This is an example request from the official Dropbox SDK:

dbapi-2://1/connect?k=9gg2zssmv7XXXXX&s=&state=oauth2code:kiCBUKN79D3O3hGI_eR0y7zikhTW0R7vY_dD-DeuLf4:S256:offline:account_info.read&extra_query_params=code_challenge%3DkiCBUKN79D3O3hGI_eR0y7zikhTW0R7vY_dD-DeuLf4%26code_challenge_method%3DS256%26token_access_type%3Doffline%26response_type%3Dcode%26scope%3Daccount_info.read

The notable changes are:

I added both changes to the URL generated in the -[TJDropbox dropboxAppAuthenticationURLWithClientIdentifier:codeVerifier:] method, and could successfully get an access token with a refresh token.

(Actually, just adding "offline" to the state parameter seems to work, but it's better to do the same as the official SDK and do both changes).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.