Skip to content

DougPuchalski/afmotion

 
 

Repository files navigation

AFMotion

AFMotion is a thin RubyMotion wrapper for AFNetworking, the absolute best networking library on iOS.

Usage

AFMotion can be used with standalone URL requests:

AFMotion::HTTP.get("http://google.com") do |result|
  p result.body
end

AFMotion::JSON.get("http://jsonip.com") do |result|
  p result.object["ip"]
end

Web Services

If you're interacting with a web service, you can use AFHTTPClient with this nice wrapper:

# DSL Mapping to properties of AFHTTPClient

AFMotion::Client.build_shared("https://alpha-api.app.net/") do
  header "Accept", "application/json"

  operation :json
end

AFMotion::Client.shared.get("stream/0/posts/stream/global") do |result|
  if result.success?
    p result.object
  elsif result.failure?
    p result.error.localizedDescription
  end
end

Images

Loading images from the internet is pretty common. AFNetworking's existing methods aren't bad at all, but just incase you want extra Ruby:

  image_view = UIImageView.alloc.initWithFrame CGRectMake(0, 0, 100, 100)
  image_view.url = "http://i.imgur.com/r4uwx.jpg"

  # or

  placeholder = UIImage.imageNamed "placeholder-avatar"
  image_view.url = {url: "http://i.imgur.com/r4uwx.jpg", placeholder: placeholder}

You can also request arbitrary images:

  AFMotion::Image.get("https://www.google.com/images/srpr/logo3w.png") do |result|
    image_view = UIImageView.alloc.initWithImage(result.object)
  end

Install

  1. gem install afmotion

  2. require 'afmotion' or add to your Gemfile

  3. In your Rakefile, add:

Motion::Project::App.setup do |app|
  ...

  app.pods do
    pod 'AFNetworking'
  end
end

Overview

Results

Each AFMotion wrapper callback yields an AFMotion::HTTPResult object. This object has properties like so:

AFMotion::some_function do |result|
  # result.operation is the AFURLConnectionOperation instance
  p result.operation.inspect

  if result.success?
    # result.object depends on the type of operation.
    # For JSON and PLIST, this is usually a Hash.
    # For XML, this is an NSXMLParser
    # For HTTP, this is an NSURLResponse
    # For Image, this is a UIImage
    p result.object

  elsif result.failure?
    # result.error is an NSError
    p result.error.localizedDescription
  end
end

Operations

There are wrappers for each AFURLConnectionOperation subclass, each of the form:

AFMotion::Operation::[Operation Type].for_request(ns_url_request) do |result|
  ...
end
  • AFMotion::Operation::HTTP.for_request...
  • AFMotion::Operation::JSON.for_request...
  • AFMotion::Operation::XML.for_request...
  • AFMotion::Operation::PLIST.for_request...
  • AFMotion::Operation::Image.for_request...

One-off Requests

There are wrappers which automatically run a URL request for a given URL and HTTP method, of the form:

AFMotion::[Operation Type].[HTTP method](url, [Parameters = {}]) do |result|
  ...
end

Example:

AFMotion::HTTP.get("http://google.com", q: "rubymotion") do |result|
  # sends request to http://google.com?q=rubymotion
end
  • AFMotion::HTTP.get/post/put/patch/delete(url)...
  • AFMotion::JSON.get/post/put/patch/delete(url)...
  • AFMotion::XML.get/post/put/patch/delete(url)...
  • AFMotion::PLIST.get/post/put/patch/delete(url)...
  • AFMotion::Image.get/post/put/patch/delete(url)...

HTTP Client

If you're constantly accesing a web service, it's a good idea to use an AFHTTPClient. Things lets you add a common base URL and request headers to all the requests issued through it, like so:

client = AFMotion::Client.build("https://alpha-api.app.net/") do
  header "Accept", "application/json"

  operation :json
end

client.get("stream/0/posts/stream/global") do |result|
  ...
end

If you're constantly used one web service, you can use the AFMotion::Client.shared variable have a common reference. It can be set like a normal variable or created with AFMotion::Client.build_shared.

AFHTTPClient supports methods of the form AFHTTPClient#get/post/put/patch/delete(url, request_parameters). The request_parameters is a hash containing your parameters to attach as the request body or URL parameters, depending on request type. For example:

client.get("users", id: 1) do |result|
  ...
end

client.post("users", name: "@clayallsopp", library: "AFMotion") do |result|
  ...
end

Multipart Requests

AFHTTPClient supports multipart form requests (i.e. for image uploading). Simply prepend multipart to any other request method and it'll convert your parameters into properly encoded multipart data:

# an instance of UIImage
image = my_function.get_image
data = UIImagePNGRepresentation(image)

client.multipart.post("avatars") do |result, form_data|
  if form_data
    # Called before request runs
    # see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
    form_data.appendPartWithFileData(data, name: "avatar", fileName:"avatar.png", mimeType: "image/png")
  elsif result.success?
    ...
  else
    ...
  end
end

If you want to track upload progress, you can add a third callback argument which returns the upload percentage between 0.0 and 1.0:

client.multipart.post("avatars") do |result, form_data, progress|
  if form_data
    # Called before request runs
    # see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
    form_data.appendPartWithFileData(data, name: "avatar", fileName:"avatar.png", mimeType: "image/png")
  elsif progress
    # 0.0 <= progress <= 1.0
    my_widget.update_progress(progress)
  ...
end

Client Building DSL

The AFMotion::Client DSL allows the following properties:

  • header(header, value)
  • authorization(username: ___, password: ____) for HTTP Basic auth, or authorization(token: ____) for Token based auth.
  • operation(operation_type). Allows you to set a common operation class for all your client's requests. So if your API is always going to be JSON, you should set operation(:json). Accepts :json, :plist, :xml, or :http
  • parameter_encoding(encoding). Allows you to set a body format for requests parameters. For example, when you send a POST request you might want the parameters to be encoding as a JSON object instead of the traditional key=val format. Accepts :json, :plist, and :form (normal encoding).

About

AFMotion is a thin RubyMotion wrapper for AFNetworking

Resources

Stars

Watchers

Forks

Packages

No packages published