Basetask

Easy NSURLSession Networking

View project on GitHub

BaseTask is a set of classes that allow you to easily create an API client for a web service. It reduces the boilerplate down to just the specifics you need to interact with an API.

Build Status Coverage Status License Platform CocoaPods Carthage compatible

Motivation

When building applications that interact with web services, I wanted something that took advantage of the existing NSURLSession classes that Apple introduced with iOS 7 and OSX 10.9. I also wanted something that could be subclassed so I could encapsulate different web resource requests within concreate classes that only add in their specific details.

Features

  • Small public API surface
  • Works with your own custom objects
  • Customizeable via method override
  • Well documented
  • Tested
  • Support For Cocoapods/Carthage integration

Installation

Carthage

Add the following to your Cartfile:

github "Endoze/BaseTask"

Then add the framework as a linked framework.

CocoaPods

Add the following to your Podfile:

use_frameworks!


pod 'BaseTask'

Then run pod install

Show me the code

If your language of choice is Swift

// UserTask.swift

import BaseTask

class PostTask: BaseTask {
  typealias Post = [String: AnyObject]
  typealias GetPostCompletionHandler = (Post?, NSURLResponse?, NSError?) -> Void
  typealias GetAllPostsCompletionHandler = ([Post]?, NSURLResponse?, NSError?) -> Void

  let baseURLString = "http://jsonplaceholder.typicode.com/posts"

  func getPost(id: String, completionHandler: GetPostCompletionHandler) -> NSURLSessionDataTask {
    let url = NSURL(string: "\(baseURLString)/\(id)")!

    return makeHTTPRequest(url,
      bodyDictionary: nil,
      httpMethod: .Get,
      httpHeaders: nil,
      bodyParser: nil,
      responseParsers: [JSONResponseParser()],
      completion: { (parsedObject, response, error) in
        let objectToReturn = parsedObject as? Post
        completionHandler(objectToReturn, response, error)
      }
    )
  }

  func getAllPosts(completionHandler: GetAllPostsCompletionHandler) -> NSURLSessionDataTask {
    let url = NSURL(string: baseURLString)!

    return makeHTTPRequest(url,
      bodyDictionary: nil,
      httpMethod: .Get,
      httpHeaders: nil,
      bodyParser: nil,
      responseParsers: [JSONResponseParser()],
      completion: { (parsedObject, response, error) in
        let objectToReturn = parsedObject as? [Post]
        completionHandler(objectToReturn, response, error)
    })
  }
}
// Elsewhere

let task = PostTask().getAllPosts() { posts, response, error in
  if let posts = posts where error == nil {
    // do something with posts
    print(posts)
  }
}

task.resume()

Or if you prefer Objective-C

// PostTask.h

#import "BaseTask.h"

typedef NSDictionary<NSString *, id> Post;
typedef void (^GetAllPostsCallback)(NSArray<Post *> * _Nullable posts, NSURLResponse * _Nullable response, NSError * _Nullable error);

@interface PostTask : BaseTask

- (NSString *)baseURL;

- (void)getAllPostsWithCompletionHandler:(GetAllPostsCallback)completionHandler;

@end
// PostTask.m

#import "PostTask.h"

@implementation PostTask

- (NSString *)baseURL
{
    return @"http://jsonplaceholder.typicode.com/posts";
}

- (void)getAllPostsWithCompletionHandler:(GetAllPostsCallback)completionHandler
{
    NSURL *url = [NSURL URLWithString:[self baseURL]];

  return [self makeHTTPRequest:url
                bodyDictionary:nil
                    httpMethod:GET
                   httpHeaders:nil
                    bodyParser:nil
               responseParsers:@[[JSONResponseParser new]]
                dispatch_queue:nil
                    completion:completionHandler];
}

@end
// Elsewhere

NSURLSessionDataTask *task = [[PostTask new]
 getAllPostsWithCompletionHandler:^(NSArray<Post *> *posts, NSURLResponse *response, NSError *error) {
    if (!error && posts) {
      // do something with posts
        NSLog(@"%@", posts);
    }
}];

[task resume];