Code Monkey home page Code Monkey logo

objectivehub's Introduction

ObjectiveHub

An Objective-C (ARC enabled) library for version 3 of the GitHub API, for iOS 5.0+ and Mac OS X 10.7+.

The official website holds an [API reference guide]((http://libobjectivehub.com/docs) and some guides on how to work with ObjectiveHub.

The development speed and growth of ObjectiveHub is bound by the rate of the documentation. That is O(documentation), just like nimbus.

Getting Started

Please see the getting started wiki page or the tutorial Your First ObjectiveHub App (or the Mac OS X version of the tutorial).

Requirements

Requires iOS 5.0+ or Mac OS X 10.7 during runtime and Xcode 4.2+ with the iOS 5 or Mac OS X 10.7 SDK to build.

Documentation

ObjectiveHub documentation.

Hacking

The project follows the git flow model laid out by nvie in his blog-post "A syccessful Git branching model". This means that all development occur on the develop branch and the master branch is reserved for stable releases.

Furthermore, the project use semantic versioning and there will be one tag per version as well as possibly a support branch. That is when version 1.1.0 is introduced a support branch for 1.0.x might be created as support/1.0 and so on.

ObjectiveHub contributors

You can help improve the documentation, code quality and feature list. Either by contributing directly to the project, filing bug reports or by donating to keep the development going. It is all greatly appreciated!

Source code contributors (alphabetically by last name)

Misc information

The project use semantic versioning and the git repository is maintained using git flow. As such all active development takes place on the develop branch or a feature branch (prefixed with feature/ followed by an identifier). The master branch is dedicated for the latest stable version.

License

The project is licensed under the "Simplified BSD license" (2-clause), for the exact terms please see the LICENSE file.

objectivehub's People

Contributors

rastersize avatar

Stargazers

 avatar  avatar

Watchers

 avatar James Cloos avatar  avatar

objectivehub's Issues

Create user for unit tests

Since the framework will have a lot of unit tests I (@rastersize) must create a unit tests user (also to make sure things like "unwatch" of repos are possible without messing up my account).

Bump deployment versions

The OS X framework version should be bumped to 10.7 and the iOS library to 5.0. The reason being that these (and up) are the only versions I can test on due to time, will and resource constraints.

Unit tests not passing for CDOHRepository

Test Case '-[CDOHRepositoryTests testResourceEncodeAsDictionary]' started.
/Users/aron/Projects/Projects/Personal/ObjectiveHub/ObjectiveHub-Tests/CDOHResourceBaseTests.m:173: error: -[CDOHRepositoryTests testResourceEncodeAsDictionary] : '{
    "clone_url" = "https://github.com/rastersize/developer.github.com.git";
    "created_at" = "2012-02-13T21:45:50Z";
    description = "GitHub API documentation";
    fork = 1;
    forks = 0;
    "git_url" = "git://github.com/rastersize/developer.github.com.git";
    "has_downloads" = 1;
    "has_issues" = 0;
    "has_wiki" = 1;
    homepage = "http://developer.github.com";
    "html_url" = "https://github.com/rastersize/developer.github.com";
    id = 3434443;
    language = Ruby;
    "master_branch" = "<null>";
    "mirror_url" = "<null>";
    name = "developer.github.com";
    "open_issues" = 0;
    organization =     {
        "avatar_url" = "https://secure.gravatar.com/avatar/61024896f291303615bcd4f7a0dcfb74?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-orgs.png";
        "gravatar_id" = 61024896f291303615bcd4f7a0dcfb74;
        id = 9919;
        login = github;
        url = "https://api.github.com/users/github";
    };
    owner =     {
        "avatar_url" = "https://secure.gravatar.com/avatar/2f21aac393665a85428eab10c2bdbe79?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png";
        "gravatar_id" = 2f21aac393665a85428eab10c2bdbe79;
        id = 23453;
        login = rastersize;
        url = "https://api.github.com/users/rastersize";
    };
    parent =     {
        "clone_url" = "https://github.com/github/developer.github.com.git";
        "created_at" = "2011-04-26T19:20:56Z";
        description = "GitHub API documentation";
        fork = 0;
        forks = 65;
        "git_url" = "git://github.com/github/developer.github.com.git";
        "has_downloads" = 1;
        "has_issues" = 1;
        "has_wiki" = 1;
        homepage = "http://developer.github.com";
        "html_url" = "https://github.com/github/developer.github.com";
        id = 1666784;
        language = Ruby;
        "master_branch" = "<null>";
        "mirror_url" = "<null>";
        name = "developer.github.com";
        "open_issues" = 26;
        owner =         {
            "avatar_url" = "https://secure.gravatar.com/avatar/61024896f291303615bcd4f7a0dcfb74?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-orgs.png";
            "gravatar_id" = 61024896f291303615bcd4f7a0dcfb74;
            id = 9919;
            login = github;
            url = "https://api.github.com/users/github";
        };
        private = 0;
        "pushed_at" = "2012-02-10T22:36:35Z";
        size = 160;
        "ssh_url" = "[email protected]:github/developer.github.com.git";
        "svn_url" = "https://github.com/github/developer.github.com";
        "updated_at" = "2012-02-13T21:45:50Z";
        url = "https://api.github.com/repos/github/developer.github.com";
        watchers = 162;
    };
    private = 0;
    "pushed_at" = "2012-02-13T21:49:12Z";
    size = 132;
    source =     {
        "clone_url" = "https://github.com/github/developer.github.com.git";
        "created_at" = "2011-04-26T19:20:56Z";
        description = "GitHub API documentation";
        fork = 0;
        forks = 65;
        "git_url" = "git://github.com/github/developer.github.com.git";
        "has_downloads" = 1;
        "has_issues" = 1;
        "has_wiki" = 1;
        homepage = "http://developer.github.com";
        "html_url" = "https://github.com/github/developer.github.com";
        id = 1666784;
        language = Ruby;
        "master_branch" = "<null>";
        "mirror_url" = "<null>";
        name = "developer.github.com";
        "open_issues" = 26;
        owner =         {
            "avatar_url" = "https://secure.gravatar.com/avatar/61024896f291303615bcd4f7a0dcfb74?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-orgs.png";
            "gravatar_id" = 61024896f291303615bcd4f7a0dcfb74;
            id = 9919;
            login = github;
            url = "https://api.github.com/users/github";
        };
        private = 0;
        "pushed_at" = "2012-02-10T22:36:35Z";
        size = 160;
        "ssh_url" = "[email protected]:github/developer.github.com.git";
        "svn_url" = "https://github.com/github/developer.github.com";
        "updated_at" = "2012-02-13T21:45:50Z";
        url = "https://api.github.com/repos/github/developer.github.com";
        watchers = 162;
    };
    "ssh_url" = "[email protected]:rastersize/developer.github.com.git";
    "svn_url" = "https://github.com/rastersize/developer.github.com";
    "updated_at" = "2012-02-13T21:49:12Z";
    url = "https://api.github.com/repos/rastersize/developer.github.com";
    watchers = 1;
}' should be equal to '{
    "clone_url" = "https://github.com/rastersize/developer.github.com.git";
    description = "GitHub API documentation";
    "git_url" = "git://github.com/rastersize/developer.github.com.git";
    "html_url" = "https://github.com/rastersize/developer.github.com";
    id = 3434443;
    language = Ruby;
    "master_branch" = "<null>";
    name = "developer.github.com";
    "ssh_url" = "[email protected]:rastersize/developer.github.com.git";
    "svn_url" = "https://github.com/rastersize/developer.github.com";
    url = "https://api.github.com/repos/rastersize/developer.github.com";
}' Creating a resource (<CDOHRepository: 0x1032d75e0 { rastersize/developer.github.com }>) from a dictionary ({
    "clone_url" = "https://github.com/rastersize/developer.github.com.git";
    "created_at" = "2012-02-13T21:45:50Z";
    description = "GitHub API documentation";
    fork = 1;
    forks = 0;
    "git_url" = "git://github.com/rastersize/developer.github.com.git";
    "has_downloads" = 1;
    "has_issues" = 0;
    "has_wiki" = 1;
    homepage = "http://developer.github.com";
    "html_url" = "https://github.com/rastersize/developer.github.com";
    id = 3434443;
    language = Ruby;
    "master_branch" = "<null>";
    "mirror_url" = "<null>";
    name = "developer.github.com";
    "open_issues" = 0;
    organization =     {
        "avatar_url" = "https://secure.gravatar.com/avatar/61024896f291303615bcd4f7a0dcfb74?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-orgs.png";
        "gravatar_id" = 61024896f291303615bcd4f7a0dcfb74;
        id = 9919;
        login = github;
        url = "https://api.github.com/users/github";
    };
    owner =     {
        "avatar_url" = "https://secure.gravatar.com/avatar/2f21aac393665a85428eab10c2bdbe79?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png";
        "gravatar_id" = 2f21aac393665a85428eab10c2bdbe79;
        id = 23453;
        login = rastersize;
        url = "https://api.github.com/users/rastersize";
    };
    parent =     {
        "clone_url" = "https://github.com/github/developer.github.com.git";
        "created_at" = "2011-04-26T19:20:56Z";
        description = "GitHub API documentation";
        fork = 0;
        forks = 65;
        "git_url" = "git://github.com/github/developer.github.com.git";
        "has_downloads" = 1;
        "has_issues" = 1;
        "has_wiki" = 1;
        homepage = "http://developer.github.com";
        "html_url" = "https://github.com/github/developer.github.com";
        id = 1666784;
        language = Ruby;
        "master_branch" = "<null>";
        "mirror_url" = "<null>";
        name = "developer.github.com";
        "open_issues" = 26;
        owner =         {
            "avatar_url" = "https://secure.gravatar.com/avatar/61024896f291303615bcd4f7a0dcfb74?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-orgs.png";
            "gravatar_id" = 61024896f291303615bcd4f7a0dcfb74;
            id = 9919;
            login = github;
            url = "https://api.github.com/users/github";
        };
        private = 0;
        "pushed_at" = "2012-02-10T22:36:35Z";
        size = 160;
        "ssh_url" = "[email protected]:github/developer.github.com.git";
        "svn_url" = "https://github.com/github/developer.github.com";
        "updated_at" = "2012-02-13T21:45:50Z";
        url = "https://api.github.com/repos/github/developer.github.com";
        watchers = 162;
    };
    private = 0;
    "pushed_at" = "2012-02-13T21:49:12Z";
    size = 132;
    source =     {
        "clone_url" = "https://github.com/github/developer.github.com.git";
        "created_at" = "2011-04-26T19:20:56Z";
        description = "GitHub API documentation";
        fork = 0;
        forks = 65;
        "git_url" = "git://github.com/github/developer.github.com.git";
        "has_downloads" = 1;
        "has_issues" = 1;
        "has_wiki" = 1;
        homepage = "http://developer.github.com";
        "html_url" = "https://github.com/github/developer.github.com";
        id = 1666784;
        language = Ruby;
        "master_branch" = "<null>";
        "mirror_url" = "<null>";
        name = "developer.github.com";
        "open_issues" = 26;
        owner =         {
            "avatar_url" = "https://secure.gravatar.com/avatar/61024896f291303615bcd4f7a0dcfb74?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-orgs.png";
            "gravatar_id" = 61024896f291303615bcd4f7a0dcfb74;
            id = 9919;
            login = github;
            url = "https://api.github.com/users/github";
        };
        private = 0;
        "pushed_at" = "2012-02-10T22:36:35Z";
        size = 160;
        "ssh_url" = "[email protected]:github/developer.github.com.git";
        "svn_url" = "https://github.com/github/developer.github.com";
        "updated_at" = "2012-02-13T21:45:50Z";
        url = "https://api.github.com/repos/github/developer.github.com";
        watchers = 162;
    };
    "ssh_url" = "[email protected]:rastersize/developer.github.com.git";
    "svn_url" = "https://github.com/rastersize/developer.github.com";
    "updated_at" = "2012-02-13T21:49:12Z";
    url = "https://api.github.com/repos/rastersize/developer.github.com";
    watchers = 1;
}) and then encoding it as a dictionary ({
    "clone_url" = "https://github.com/rastersize/developer.github.com.git";
    description = "GitHub API documentation";
    "git_url" = "git://github.com/rastersize/developer.github.com.git";
    "html_url" = "https://github.com/rastersize/developer.github.com";
    id = 3434443;
    language = Ruby;
    "master_branch" = "<null>";
    name = "developer.github.com";
    "ssh_url" = "[email protected]:rastersize/developer.github.com.git";
    "svn_url" = "https://github.com/rastersize/developer.github.com";
    url = "https://api.github.com/repos/rastersize/developer.github.com";
}) should yeild an identical dictionary
Test Case '-[CDOHRepositoryTests testResourceEncodeAsDictionary]' failed (0.064 seconds).

Make resources and Core Data fall in love

The resources (CDOHResource descendants) should by manageable by Core Data. This includes being created, saved and all other niceties that Core Data provides.

Could this be achieved by changing CDOHResource to inherit NSManagedObject? Maybe by doing this we could fix part of #7 ("Use lazy recognition for resources") by letting the NSManagedObject class handle all the @dynamic properties.

Missing API docs for Core Data attributes/relations

API documentation missing for some classes and methods/properties. This primarily affects all the properties of the resources as they exist in Core Data and the generated machine classes contain their properties and methods. These are replaced each time we update the Core Data model.

No public request parameter keys.

We no longer expose the constants matching GitHub’s JSON API-keys, let’s add public request parameter keys instead and update the documentation to reflect this.

Be network library agnostic

Look into supporting any (via a proxy class or something similar) network library. This would allow the user of the library to include the library she prefers, we could also remove AFNetworking from this repository (thus not causing duplicate symbol errors).

Possible libraries

  • AFNetworking
  • MKNetworkKit
  • Plain old Cocoa (Touch) NSURLConnection.

Crashes when encoding a CDOHRepository to a dictionary

Crashes with:

2012-02-13 10:13:37.891 PM com.__redacted__: *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[__NSCFString absoluteString]:
unrecognized selector sent to instance 0x7f9c0aca4180'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff8ea24fc6 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff8a3a5d5e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff8eab12ae -[NSObject doesNotRecognizeSelector:] + 190
    3   CoreFoundation                      0x00007fff8ea11e73 ___forwarding___ + 371
    4   CoreFoundation                      0x00007fff8ea11c88 _CF_forwarding_prep_0 + 232
    5   ObjectiveHub                        0x0000000108c3e68c -[CDOHRepository encodeAsDictionary] + 1100
    6   com.__redacted__                    0x0000000108be9e4d __block_global_1 + 2477
    7   ObjectiveHub                        0x0000000108c340c9 __93-[CDOHClient standardSuccessBlockWithResourceCreationBlock:success:failure:action:arguments:]_block_invoke_0 + 441
    8   ObjectiveHub                        0x0000000108c28dbb __block_global_1 + 75
    9   libdispatch.dylib                   0x00007fff8e8e18ba _dispatch_call_block_and_release + 18
    10  libdispatch.dylib                   0x00007fff8e8e310a _dispatch_queue_drain + 264
    11  libdispatch.dylib                   0x00007fff8e8e2f66 _dispatch_queue_invoke + 54
    12  libdispatch.dylib                   0x00007fff8e8e2760 _dispatch_worker_thread2 + 198
    13  libsystem_c.dylib                   0x00007fff897523da _pthread_wqthread + 316
    14  libsystem_c.dylib                   0x00007fff89753b85 start_wqthread + 13
)

Add internal cache

The library should cache certain requests, in memory and to disk, if the application want's it to do that. Using sensible amounts of data and time limits (resources with a cache time shorter than or equal to 5 minutes should for example not be cached at all).

Use lazy recognition for resources

CDOHResource should implement lazy recognition so that subclasses (concrete) resources can just declare their properties and then use @dynamic to get the lazily created and recognized by CDOHResource. This approach would also allow CDOHResource to a bunch of common methods generically (see below for a list).

  • -isEqual:
  • -isEqualToResource:
  • -hash
  • -initWithDictionary:
  • -initWithCode:
  • -encodeWithCoder:
  • -description

The initWithDictionary: and encodeWithCoder: methods could use the type of the properties (via the method signatures) to apply any type of default special behavior. This could, but should not be limited to, include the types;

  • NSDate (might need to be parsed from an RFC 3339 formatted string).
  • Subclass of CDOHResource (might need to be initiated with a dictionary).

Need a camelCase to separated_by_underscore converter so that we do not even need to define the GitHub API keys. This would also require us to adopt the new "link" suffix that is going to be used by GitHub soon. The converter would also need to convert the entire string to lowercase.

Change how the resource unit tests work

It would probably be much better if the the unit tests declared what type of object each resource property accepts and then let the base class generate tests that should be acceptable. This would allow us to test more edge cases and so forth.

Minimize dependency

We should depend on as few external projects as possible so that users of this framework does not have to battle with duplicate symbol problems. As such we should stop using JSONKit and instead use the built-in support.

All resources should be convertible to XPC objects

It should be possible for a client of the library to convert any resource (CDOHResource and its subclasses) and the instances of CDOHError to a XPC object. The best approach is probably to add a -dictionaryRepresentation (alternatively -encodeAsDictionary) method to the classes. The method would then return a NSDictionary object which represents the real object and can be used to instantiate a new identical object using the -initWithDictionary: method for resources and -initWithDomain:code:userInfo:.

Support offline actions

If the device lacks connectivity with GitHub (due to it being offline or GitHub being down) at the time of the request it should be put into a queue and executed when we once again have connectivity.

All *_url fields will be renamed to *_link

GitHub will soon change the API to use whatever_link instead of whatever_url. This means that ObjectiveHub will break. The ObjectiveHub API will not change its property names but will of course update itself so that the correct values are found.

Use NSIndexSet instead of NSArray for pages

Instead of using NSArray, which is a bit cumbersome (see below), we should use NSIndexSet for the …pages: … parameter to the client methods.

NSArray *pages = [NSArray arrayWithObjects:[NSNumber numberWithInteger:1], …, nil];
// vs.
NSIndexSet *pages = [NSIndexSet indexSetWithIndexesInRange:NSRange(0, N)];
// Where 'N' is the last page.

Change client protocol to be compatible with XPC services

To be fully compatible with XPC services we should only use one response block.

That is, the following method…

 - (void)repository:(NSString *)repository owner:(NSString *)owner
            success:(CDOHResponseBlock)successBlock
            failure:(CDOHFailureBlock)failureBlock;

…should become:

- (void)repository:(NSString *)repository owner:(NSString *)owner
     responseBlock:(CDOHResponseBlock)responseBlock;

Where CDOHResponseBlock would have the following type: void (^)(CDOHResponse *response). The class CDOHResponse should also be extended with one or two properties, namely success and/or error. Where error would be nil if success is YES.

Why? Well it because [REDACTED!!!].

References

Look into using MKNetworkKit instead of AFNetworking

We might want to use MKNetworkKit instead of AFNetworking as it comes with a few niceties which would solve issue #1, #2 and #3 as well as other cool things. Biggest issue at the moment seems to be spotty Mac OS X support.

Does it support OS X 10.6 and iOS 4.2? Can we make AFNetworking do this for us, does it already do it or is it on the way?

Not capturing "contributions" data

When getting the contributors for a specific repository GitHub returns a field called "contributions" (number) detailing how many contributions each user has done to the repository. Currently we do not capture this data and as such it is lost.

Example response (for /repos/twitter/bootstrap/contributors):

[
  {
    "contributions": 553,
    "url": "https://api.github.com/users/markdotto",
    "avatar_url": "https://secure.gravatar.com/avatar/bc4ab438f7a4ce1c406aadc688427f2c?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
    "gravatar_id": "bc4ab438f7a4ce1c406aadc688427f2c",
    "login": "markdotto",
    "id": 98681
  },
  …
]

Big ass memory leak somewhere

We seem to hit a big ass memory leak when running the unit tests multiple times. The memory is not even deallocated when Xcode is quit. The problem occurs in the testResourceEquality and/or testResourceHash when running tests for CDOHRepository, the execution freezes and memory seems to not be deallocated properly.

Request methods should return something to hold onto

The request methods should return some object that the user can hold onto in case she want to cancel the specific request or in some other way modify the request after it has been made.

Suggestions on what it can do

  • Cancel the request.
  • Suspend the request.
  • Resume a suspended request.
  • Check request progress (for updating finite progress indicator and so on).

Investigate using path formats with named keys

The current API path formats (e.g. /repos/%@/%@/%@) are rather fragile and not very maintainable as the arguments are some times passed in the wrong order (easy to fix but annoying). If the formats need to change for some reason that will require a lot of going through and making sure it is not used in the wrong way. Furthermore, from the current format it is not very easy to understand what is supposed to go where.

To solve this we could use named keys inside the path formats. For example /repos/:owner/:name/:extra for getting some extra information, such as forks, about a repository named :name and owned by :owner. The path strings could be defined using this format and a method of CDOHClient could then take a dictionary of options and search and replace for those.

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.