Git Product home page Git Product logo

octokit.objc's Introduction

NOTE: This repository is no longer supported or updated by GitHub. If you wish to continue to develop this code yourself, we recommend you fork it.

OctoKit

Carthage compatible

OctoKit is a Cocoa and Cocoa Touch framework for interacting with the GitHub API, built using AFNetworking, Mantle, and ReactiveCocoa.

Making Requests

In order to begin interacting with the API, you must instantiate an OCTClient. There are two ways to create a client without authenticating:

  1. -initWithServer: is the most basic way to initialize a client. It accepts an OCTServer, which determines whether to connect to GitHub.com or a GitHub Enterprise instance.
  2. +unauthenticatedClientWithUser: is similar, but lets you set an active user, which is required for certain requests.

We'll focus on the second method, since we can do more with it. Let's create a client that connects to GitHub.com:

OCTUser *user = [OCTUser userWithRawLogin:username server:OCTServer.dotComServer];
OCTClient *client = [OCTClient unauthenticatedClientWithUser:user];

After we've got a client, we can start fetching data. Each request method on OCTClient returns a ReactiveCocoa signal, which is kinda like a future or promise:

// Prepares a request that will load all of the user's repositories, represented
// by `OCTRepository` objects.
//
// Note that the request is not actually _sent_ until you use one of the
// -subscribe… methods below.
RACSignal *request = [client fetchUserRepositories];

However, you don't need a deep understanding of RAC to use OctoKit. There are just a few basic operations to be aware of.

Receiving results one-by-one

It often makes sense to handle each result object independently, so you can spread any processing out instead of doing it all at once:

// This method actually kicks off the request, handling any results using the
// blocks below.
[request subscribeNext:^(OCTRepository *repository) {
    // This block is invoked for _each_ result received, so you can deal with
    // them one-by-one as they arrive.
} error:^(NSError *error) {
    // Invoked when an error occurs.
    //
    // Your `next` and `completed` blocks won't be invoked after this point.
} completed:^{
    // Invoked when the request completes and we've received/processed all the
    // results.
    //
    // Your `next` and `error` blocks won't be invoked after this point.
}];

Receiving all results at once

If you can't do anything until you have all of the results, you can "collect" them into a single array:

[[request collect] subscribeNext:^(NSArray *repositories) {
    // Thanks to -collect, this block is invoked after the request completes,
    // with _all_ the results that were received.
} error:^(NSError *error) {
    // Invoked when an error occurs. You won't receive any results if this
    // happens.
}];

Receiving results on the main thread

The blocks in the above examples will be invoked in the background, to avoid slowing down the main thread. However, if you want to run UI code, you shouldn't do it in the background, so you must "deliver" results to the main thread instead:

[[request deliverOn:RACScheduler.mainThreadScheduler] subscribeNext:^(OCTRepository *repository) {
    // ...
} error:^(NSError *error) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Whoops!"
                                                    message:@"Something went wrong."
                                                   delegate:nil
                                          cancelButtonTitle:nil
                                          otherButtonTitles:nil];
    [alert show];
} completed:^{
    [self.tableView reloadData];
}];

Cancelling a request

All of the -subscribe… methods actually return a RACDisposable object. Most of the time, you don't need it, but you can hold onto it if you want to cancel requests:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    RACDisposable *disposable = [[[[self.client
        fetchUserRepositories]
        collect]
        deliverOn:RACScheduler.mainThreadScheduler]
        subscribeNext:^(NSArray *repositories) {
            [self addTableViewRowsForRepositories:repositories];
        } error:^(NSError *error) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Whoops!"
                                                            message:@"Something went wrong."
                                                           delegate:nil
                                                  cancelButtonTitle:nil
                                                  otherButtonTitles:nil];
            [alert show];
        }];

    // Save the disposable into a `strong` property, so we can access it later.
    self.repositoriesDisposable = disposable;
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    // Cancels the request for repositories if it's still in progress. If the
    // request already terminated, nothing happens.
    [self.repositoriesDisposable dispose];
}

Authentication

OctoKit supports two variants of OAuth2 for signing in. We recommend the browser-based approach, but you can also implement a native sign-in flow if desired.

In both cases, you will need to register your OAuth application, and provide OctoKit with your client ID and client secret before trying to authenticate:

[OCTClient setClientID:@"abc123" clientSecret:@"654321abcdef"];

Signing in through a browser

With this API, the user will be redirected to their default browser (on OS X) or Safari (on iOS) to sign in, and then redirected back to your app. This is the easiest approach to implement, and means the user never has to enter their password directly into your app — plus, they may even be signed in through the browser already!

To get started, you must implement a custom URL scheme for your app, then use something matching that scheme for your OAuth application's callback URL. The actual URL doesn't matter to OctoKit, so you can use whatever you'd like, just as long as the URL scheme is correct.

Whenever your app is opened from your URL, or asked to open it, you must pass it directly into OCTClient:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)URL sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    // For handling a callback URL like my-app://oauth
    if ([URL.host isEqual:@"oauth"]) {
        [OCTClient completeSignInWithCallbackURL:URL];
        return YES;
    } else {
        return NO;
    }
}

After that's set up properly, you can present the sign in page at any point. The pattern is very similar to making a request, except that you receive an OCTClient instance as a reply:

[[OCTClient
    signInToServerUsingWebBrowser:OCTServer.dotComServer scopes:OCTClientAuthorizationScopesUser]
    subscribeNext:^(OCTClient *authenticatedClient) {
        // Authentication was successful. Do something with the created client.
    } error:^(NSError *error) {
        // Authentication failed.
    }];

You can also choose to receive the client on the main thread, just like with any other request.

Signing in through the app

If you don't want to open a web page, you can use the native authentication flow and implement your own sign-in UI. However, two-factor authentication makes this process somewhat complex, and the native authentication flow may not work with GitHub Enterprise instances that use single sign-on.

Whenever the user wants to sign in, present your custom UI. After the form has been filled in with a username and password (and perhaps a server URL, for GitHub Enterprise users), you can attempt to authenticate. The pattern is very similar to making a request, except that you receive an OCTClient instance as a reply:

OCTUser *user = [OCTUser userWithRawLogin:username server:OCTServer.dotComServer];
[[OCTClient
    signInAsUser:user password:password oneTimePassword:nil scopes:OCTClientAuthorizationScopesUser]
    subscribeNext:^(OCTClient *authenticatedClient) {
        // Authentication was successful. Do something with the created client.
    } error:^(NSError *error) {
        // Authentication failed.
    }];

(You can also choose to receive the client on the main thread, just like with any other request.)

oneTimePassword must be nil on your first attempt, since it's impossible to know ahead of time if a user has two-factor authentication enabled. If they do, you'll receive an error of code OCTClientErrorTwoFactorAuthenticationOneTimePasswordRequired, and should present a UI for the user to enter the 2FA code they received via SMS or read from an authenticator app.

Once you have the 2FA code, you can attempt to sign in again. The resulting code might look something like this:

- (IBAction)signIn:(id)sender {
    NSString *oneTimePassword;
    if (self.oneTimePasswordVisible) {
        oneTimePassword = self.oneTimePasswordField.text;
    } else {
        oneTimePassword = nil;
    }

    NSString *username = self.usernameField.text;
    NSString *password = self.passwordField.text;

    [[[OCTClient
        signInAsUser:username password:password oneTimePassword:oneTimePassword scopes:OCTClientAuthorizationScopesUser]
        deliverOn:RACScheduler.mainThreadScheduler]
        subscribeNext:^(OCTClient *client) {
            [self successfullyAuthenticatedWithClient:client];
        } error:^(NSError *error) {
            if ([error.domain isEqual:OCTClientErrorDomain] && error.code == OCTClientErrorTwoFactorAuthenticationOneTimePasswordRequired) {
                // Show OTP field and have the user try again.
                [self showOneTimePasswordField];
            } else {
                // The error isn't a 2FA prompt, so present it to the user.
                [self presentError:error];
            }
        }];
}

Choosing an authentication method dynamically

If you really want a native login flow without sacrificing the compatibility of browser-based login, you can inspect a server's metadata to determine how to authenticate.

However, because not all GitHub Enterprise servers support this API, you should handle any errors returned:

[[OCTClient
    fetchMetadataForServer:someServer]
    subscribeNext:^(OCTServerMetadata *metadata) {
        if (metadata.supportsPasswordAuthentication) {
            // Authenticate with +signInAsUser:password:oneTimePassword:scopes:
        } else {
            // Authenticate with +signInToServerUsingWebBrowser:scopes:
        }
    } error:^(NSError *error) {
        if ([error.domain isEqual:OCTClientErrorDomain] && error.code == OCTClientErrorUnsupportedServer) {
            // The server doesn't support capability checks, so fall back to one
            // method or the other.
        }
    }];

Saving credentials

Generally, you'll want to save an authenticated OctoKit session, so the user doesn't have to repeat the sign in process when they open your app again.

Regardless of the authentication method you use, you'll end up with an OCTClient instance after the user signs in successfully. An authenticated client has user and token properties. To remember the user, you need to save user.rawLogin and the OAuth access token into the keychain.

When your app is relaunched, and you want to use the saved credentials, skip the normal sign-in methods and create an authenticated client directly:

OCTUser *user = [OCTUser userWithRawLogin:savedLogin server:OCTServer.dotComServer];
OCTClient *client = [OCTClient authenticatedClientWithUser:user token:savedToken];

If the credentials are still valid, you can make authenticated requests immediately. If not valid (perhaps because the OAuth token was revoked by the user), you'll receive an error after sending your first request, and can ask the user to sign in again.

Importing OctoKit

OctoKit is still new and moving fast, so we may make breaking changes from time-to-time, but it has partial unit test coverage and is already being used in GitHub for Mac's production code.

To add OctoKit to your application:

  1. Add the OctoKit repository as a submodule of your application's repository.
  2. Run script/bootstrap from within the OctoKit folder.
  3. Drag and drop OctoKit.xcodeproj, OctoKitDependencies.xcodeproj, ReactiveCocoa.xcodeproj, and Mantle.xcodeproj into the top-level of your application's project file or workspace. The latter three projects can be found within the External folder.
  4. On the "Build Phases" tab of your application target, add the following to the "Link Binary With Libraries" phase:
    • On iOS, add the .a libraries for OctoKit, AFNetworking, and ISO8601DateFormatter.
    • On OS X, add the .framework bundles for OctoKit, ReactiveCocoa, Mantle, AFNetworking, and ISO8601DateFormatter. All of the frames must also be added to any "Copy Frameworks" build phase.
  5. Add $(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts/include $(inherited) to the "Header Search Paths" build setting (this is only necessary for archive builds, but it has no negative effect otherwise).
  6. For iOS targets, add -ObjC to the "Other Linker Flags" build setting.

If you would prefer to use CocoaPods, there are some OctoKit podspecs that have been generously contributed by third parties.

If you’re developing OctoKit on its own, then use OctoKit.xcworkspace.

Copying the frameworks

This is only needed on OS X.

  1. Go to the "Build Phases" tab of your application target.
  2. If you don't already have one, add a "Copy Files" build phase and target the "Frameworks" destination.
  3. Drag OctoKit.framework from the OctoKit project’s Products Xcode group into the "Copy Files" build phase you just created (or the one that you already had).
  4. A reference to the framework will now appear at the top of your application’s Xcode group, select it and show the "File Inspector".
  5. Change the "Location" to "Relative to Build Products".
  6. Now do the same (starting at step 2) for the frameworks within the External folder.

License

OctoKit is released under the MIT license. See LICENSE.md.

octokit.objc's People

Contributors

aquageek avatar barrettclark avatar benjamin-dobell avatar bigboybad avatar bkeepers avatar boidanny avatar clundie avatar codafi avatar dshankar avatar gfontenot avatar halidcisse avatar hkalexling avatar jacksonh avatar jeremyagost avatar joshaber avatar joshvera avatar jspahrsummers avatar kylef avatar leichunfeng avatar mdiep avatar nwest avatar phatblat avatar rastersize avatar readmecritic avatar rizumita avatar robrix avatar ruiaaperes avatar skylar avatar tomliu avatar yorkie 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  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  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  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

octokit.objc's Issues

Getting started guide does not cover everything

Hey there! Even though the getting started guide was recently improved as per #67 it does unfortunately not cover all that is need to get started. The most recent version is missing instructions regarding Mantle and that both the sub-frameworks (Mantle and ReactiveCocoa) must also be copied in the “Copy Bundle Frameworks” build phase. That is obviously when using the library in an OS X application.

As a solution I suggest extending the readme to something like what I have done in my fork. Alternatively that the project be modified to bundle both ReactiveCocoa and Mantle. The latter would probably make it easier to include the project but harder to use your own version of ReactiveCocoa or Mantle (although that might cause issues anyway).

Any of the methods (updating the getting started guide or bundling the sub-frameworks) would be fine for me. As such I’ve prepared two pull requests one for each of the solutions, thus please have a look at #69 (getting started guide) and #70 (framework bundling).

Add support for CocoaPods

CocoaPods describes itself as "The best way to manage library dependencies in Objective-C projects."

It'd be awesome to see Octokit on CocoaPods, as it takes a lot of the hassle away using dependencies in XCode projects (especially open source ones).

Documentation?

I am generally curious about the functionality and workings of OctoKit and would like to learn more and get a feel for it before committing myself to using it.

Is there documentation somewhere? The wiki seems to not exist, and I couldn't find anything in a quick peek through the repo, nor is there a link from the read me.

If not, please consider this a request to create some, or maybe point to a good resource elsewhere online.

Authentication is confusing

It's not obvious that a new OCTClient has to be created once logged in (to set the authorization header correctly), and the existence of the -login method is kinda confusing on its own.

This might be a good opportunity to remove OCTUser.password and just pass it explicitly to the few methods that need it.

Building out of the box

Created new xcode project, followed instructions per readme and get the follow error.

OctoKit-Prefix.pch:18:10: fatal error: 'Mantle/Mantle.h' file not found
        #import <Mantle/Mantle.h>
                ^
1 error generated.

I attempted to fix this issue myself by adding External/Mantle to the Octokit.xcodeproj build settings Header Search Paths. Then the process is started again with ReactiveCocoa.

OctoKit-Prefix.pch:19:10: fatal error: 'ReactiveCocoa/ReactiveCocoa.h' file not found
        #import <ReactiveCocoa/ReactiveCocoa.h>
                ^
1 error generated.

Add External/ReactiveCocoa/ReactiveCocoaFramework to Octokit.xcodeproj build settings Header Search Paths. Then finally get this error I cant resolve:

OctoKit-Prefix.pch:19:
In file included from External/ReactiveCocoa/ReactiveCocoaFramework/ReactiveCocoa/ReactiveCocoa.h:12:
External/ReactiveCocoa/ReactiveCocoaFramework/ReactiveCocoa/NSObject+RACPropertySubscribing.h:10:9: fatal error: 'ReactiveCocoa/EXTKeyPathCoding.h' file not found
#import <ReactiveCocoa/EXTKeyPathCoding.h>
        ^
1 error generated.

I haven't worked with xcode much, what am I missing?

Why 2FA not works?

I implemented 2FA authentication as advised.
It always returns:

Error Domain=OCTClientErrorDomain Code=666 "Sign In Required" UserInfo=0x16f120b0 {NSLocalizedFailureReason=You must sign in to access user information., OCTClientErrorHTTPStatusCodeKey=401, NSLocalizedDescription=Sign In Required, OCTClientErrorRequestURLKey=https://api.github.com/authorizations/clients/fc0dfa6a2156f896acd7, NSUnderlyingError=0x16d4e6e0 "Expected status code in (200-299,304), got 401"}

Also implemented a browser based fallback, authentication works just fine. Is this a known issue?

I'm doing:

    OCTUser *user = [OCTUser userWithRawLogin:username
                                       server:OCTServer.dotComServer];
    RACSignal *signInSignal = [[OCTClient signInAsUser:user
                                              password:password
                                       oneTimePassword:oneTimePassword
                                                scopes:OCTClientAuthorizationScopesUser]
                               deliverOn:RACScheduler.mainThreadScheduler];
    [signInSignal subscribeNext:^(OCTClient *authenticatedClient)
    {
        [self storeAuthenticatedClient:authenticatedClient];
        ...

I'm using 0.5 from https://github.com/CocoaPods/Specs/blob/master/OctoKit/0.5/OctoKit.podspec

Single-page and multi-page responses may return different types

This is sucky, because we don't actually offer a way to request one page vs. multiple pages, so the caller has to be extra careful with the value they get back.

It might make sense to insert multiple pages directly into the returned signal, rather than return everything in one big array.

Star a repo

Hello!

Is it possible to star a repo using Octokit?

I know it's available in the Ruby lib, but having looked through the headers I can't seem to find an equivalent method.

-Mic

Rename for consistency with Ruby and C# clients

@pengwynn has expressed a willingness to move octokit under the github org, with a name like octokit.rb. The @github/windows library would be something like octokit.net.

Ours could be octokit.objc or octokit.cocoa or something. We can keep the existing class prefixes in the code right now. Thoughts?

Unauthenticated login causes error trying to retrieve repositories

Using the new

[OCTUser userWithRawLogin:@"login" server:[OCTServer dotComServer]];

then calling

RACSignal *request = [self.client fetchUserRepositories];
[request subscribeNext:^(OCTRepository *repository) {}]

to pull the repositories will cause an error at

- [OCTClient - (RACSignal *)enqueueUserRequestWithMethod:(NSString *)method relativePath:(NSString *)relativePath parameters:(NSDictionary *)parameters resultClass:(Class)resultClass]

since the line

path = [NSString stringWithFormat:@"users/%@%@", self.user.login, relativePath];

has self.user.login returning nil, and the rawlogin property contains the appropriate username.

Lazify requests

Requests are currently eager. It'd be nice to make them lazy + support disposal as cancelation.

Uniform handling for date/etag parameters on requests

Many endpoints allow a since parameter, If-Not-Modified header, or Etag header to omit stale results and avoid any rate limit impact if there's no new data. Since the idea is basically the same between all of these options, we could unify them on the client side.

For example, we could have some kind of OCTFreshness object (horrible name, I know) that could be instantiated from an etag or date. Methods like -fetchNotifications:…, or -fetchGists… could accept this one kind of object, instead of having multiple variations for each approach.

Tests for archive migration

Make sure that old archives can still successfully be unarchived going forward, etc.

We also need to do this for any new model versions added in the future.

-[__NSArrayI objectForKeyedSubscript:] crash

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI objectForKeyedSubscript:]: unrecognized selector sent to instance 0x7f9f2c3e99c0'
abort() called
terminate called throwing an exception

Application Specific Backtrace 1:
0   CoreFoundation                      0x00007fff88141b06 __exceptionPreprocess + 198
1   libobjc.A.dylib                     0x00007fff8ec503f0 objc_exception_throw + 43
2   CoreFoundation                      0x00007fff881d840a -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
3   CoreFoundation                      0x00007fff8813002e ___forwarding___ + 414
4   CoreFoundation                      0x00007fff8812fe18 _CF_forwarding_prep_0 + 232
5   OctoKit                             0x000000010f55eeb0 +[OCTClient errorFromRequestOperation:] + 185
6   OctoKit                             0x000000010f55d869 __54-[OCTClient enqueueRequest:resultClass:fetchAllPages:]_block_invoke122 + 73
7   OctoKit                             0x000000010f557197 __64-[AFJSONRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke_2 + 58
8   libdispatch.dylib                   0x00007fff8337df01 _dispatch_call_block_and_release + 15
9   libdispatch.dylib                   0x00007fff8337a0b6 _dispatch_client_callout + 8
10  libdispatch.dylib                   0x00007fff8337b1fa _dispatch_worker_thread2 + 304
11  libsystem_c.dylib                   0x00007fff86668d0b _pthread_wqthread + 404
12  libsystem_c.dylib                   0x00007fff866531d1 start_wqthread + 13

Auth Examples

Would it be possible to get some basic examples? I'm having a hard time sifting through the source to find methods and examples. I'm talking "Getting Started" examples.

For instance, I'm attempting a login demo doing the following, which I feel isn't correct as you can fetch user info without proper credentials. I can't seem to find a -login method.

[[self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(UIButton *sender) {
    OCTUser *user = [OCTUser userWithLogin:self.usernameTextField.text server:OCTServer.dotComServer];
    OCTClient *client = [OCTClient authenticatedClientWithUser:user password:self.passwordTextField.text];
    [[[client fetchUserInfo] deliverOn:[RACScheduler mainThreadScheduler]]
     subscribeNext:^(OCTUser *fetchedUser) {
         [GHDataStore sharedStore].client = [OCTClient authenticatedClientWithUser:fetchedUser password:self.passwordTextField.text];
     }
     error:^(NSError *error) {
         NSLog(@"Fetching error: %@",error.localizedDescription);
     }];
}];

It definitely wouldn't hurt to include a couple examples in the readme. The RAC docs are so good, that part was simple to get down following the docs. Octokit is a little bit of a slow start as I'm not quite sure what I'm doing.

No etag returned for empty responses

We currently have no way to save the etag of an empty response. This can unnecessarily impact the API limits, since we'll request the same empty data multiple times without the correct etag.

Unauthenticated requests

OCTClient currently requires a valid user to be initialized. We should allow requests to unauthenticated APIs.

"Could not open web browser", says [OCTClient signInToServerUsingWebBrowser:scopes];

Just started to use OctoKit, so far I did is no more than:

    [OCTClient setClientID:clientID clientSecret:clientSecret];
    RACSignal *signInSignal = [OCTClient signInToServerUsingWebBrowser:OCTServer.dotComServer
                                                                scopes:OCTClientAuthorizationScopesUser];
    [signInSignal subscribeNext:^(OCTClient *authenticatedClient)
    { NSLog(@"Authenticated."); }
                          error:^(NSError *error)
    { NSLog(@"Not authenticated. %@", error); }];

Which outputs:

Not authenticated. Error Domain=OCTClientErrorDomain Code=673 "Could not open web browser" UserInfo=0x176410f0 {NSLocalizedRecoverySuggestion=Please make sure you have a default web browser set., NSURL=login/oauth/authorize?client_id=<MY_CLIENT_ID>&scope=user&state=<SOME_UNIQUE_ID> -- https://github.com, NSLocalizedDescription=Could not open web browser}

Can you give me a hint on what to do next? Have not found similar issues yet. OpenURL works fine anyway, tried both simulator / device.

Bundled external ReactiveCocoa causing ARC error

Problem: The bundled ReactiveCocoa makes use of dispatch_retain and dispatch_release, which causes ARC errors for me.

Solution: Replace External/ReactiveCocoa with a pull from the ReactiveCocoa repo.

How to list commits

I currently can list the repos of a user but am not sure how to list the commits with their descriptions. How do I get a list of the commits for a particular repo along with their descriptions? The repos are being listed with the following:

    [[[client fetchUserRepositories] logAll] subscribeNext:^(id subscribe) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"info:%@",[subscribe description]);
        });
    }];

ARC not enabled in CocoaPods Podspec

I think I'm missing something obvious with OctoKit. This is a small sample app I wrote this morning:

https://github.com/jacksonh/octophile

Running this app in Instruments with the Leaks template each time I tap the Fetch User Info my OCTResponse objects are shown as leaking.

Am I doing something wrong with my subscriptions here?

iOS Tests segfault

When running the iOS Tests, I'm getting a segfault. The evidence points to a bug outside of OctoKit, likely Specta or OHHTTPStubs, but I figured I'd report the issue here first.

Within OCTClientSpec > "without a user" > "should conditionally GET a modified JSON dictionary"

A segfault occurs on OHHTTPStubs.m#L151. The segfault is caused by _requestHandlers having been dealloc'd.

Via a conditional breakpoint, the release is happening in -[SenTest performTest:], which is being invoked via Specta's SPTSenTestCase subclass, here.

I don't know Specta, but if I can help fix this, let me know where to go from here.

Cache etags for automatic conditional requests

As discussed in chat, OctoKit could automatically do something like:

  1. When the first request is made to an endpoint, store the etag that is returned (keyed by the request).
  2. When any matching future requests are made, provide the etag to the server.
  3. If the content hasn't changed, the server sends 304 Not Modified and we avoid impacting the rate limit (and, sometimes, transferring unnecessary data).

It's unclear to me whether we should cache the data associated with requests (to be provided to the consumer when the remote data is unmodified). Although it would make the concept of etags transparent, it could also result in unnecessary parsing, and makes it difficult for consumers to detect whether data has changed.

Request: 1st party CocoaPods support

Ahoy!

I'm excited about using and contributing to OctoKit, but I am being stymied right out of the gate by a lack of CocoaPods support.

The standard installation instructions all seem a bit much, especially when everything else we are using is in CocoaPods.

Unfortunately, the 3rd party PodSpec seems to be broken. It has strange dependencies (JRSwizzle), doesn't build, and doesn't seem easily fixable.

I understand that I am capable of forking this and writing my own PodSpec, and I may do so, but realistically:

  • This framework is non-trivial and I would be much more comfortable for something of this magnitude to have its own support.
    • Indeed, the promise of that is the implied promise of OctoKit as an officially supported framework.
  • As curious as I am about OctoKit, I am inclined to instead invest that time in continuing development using UAGitHubEngine.

Hypermedia support

Right now, OctoKit walks all hypermedia links manually, and expects them to be fully-constructed URLs (instead of URI templates). We should build in real hypermedia support using HAL.

What's the status of issue-and-notifications branch?

GitHub says it has been merged into master, but I see no sign of that.

After digging into the repository's history, I found a pull request (#12) which was responsible for those changes, but was never merged - seems like it was abandoned and only the notifications part was merged (#34).

If it is no longer relevant, I will be more than happy to contribute.

👐

Add to CocoaPods.

Cocoapods is an package manager for Objective-C, and it would be good to have Octokit listed there. The documentation for how to do this is here.

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.