afmotion 2.6 → 3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZGU4YjcxZDY0YTVlMmM2OTIxNzYyZDhmMDBiOGQwYjhkMzkzNDJkYg==
5
- data.tar.gz: !binary |-
6
- NDFlOWRlZmFlOTkzNTgyMTQyMGUxMzlkYWI1MDcwNDQxYjA4NWMxNg==
2
+ SHA256:
3
+ metadata.gz: b0972df3e642f569351b4c4f0897ca9969188a776751add18a3a58e0b9df0fbb
4
+ data.tar.gz: 7d6968c3d2cadd9b9b9a8185e912307bf43c2f7ed1fd26a49b0437eececa1bf3
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MWRhOGVkYzNiYTE3MDRlNmExYzQ5YTQ3N2MyYjU4ZmYxNTRlMDA5OTNiMjAx
10
- ZDI2MjMwNTVjNzA5MWM4Y2E5NmE3NTBhNWQyNWIwNTA1NGQ5NDBlNmYxNDE1
11
- Njk2MzJhMjk3YWNkMjY4OWUwYzgwYWU0Yjc3NmIzMTk3MmU4YTQ=
12
- data.tar.gz: !binary |-
13
- ZWFlYjBiNjhiZDU3NmFhNTE4ZWNiNzU2OTk3YzY5N2M3MWY2NGUxZmVkMzQ3
14
- NTZiZWU2Yzg1NzIwNTRjNjlkYzdmMDJmYTIyNTk4ZGY0YTI3ZmVlODYxMzFm
15
- NWFmZmEzM2IwN2UwM2Y5M2M5YmQwNzcxM2UwZWZhMTM1ZTRkMGU=
6
+ metadata.gz: fff5abc13b536be3b7318989271362532ebecfb9a50c7bbbfc52379eed79c575c0574f8794a1dfa13b1343fb7b0afec3d586a2481ac7a9787c3d387c05c523c1
7
+ data.tar.gz: ea3ae7b135bd574f31b0dd16ba990cc672c83823f56d6a1defe1fecdd0cbece06c066460347da7027ef7ad0b193b5ec191aa58f8582c18946dc6cb34e5740583
data/.gitignore CHANGED
@@ -14,4 +14,5 @@ nbproject
14
14
  *~
15
15
  *.sw[po]
16
16
  .eprj
17
- pkg/*
17
+ pkg/*
18
+ Gemfile.lock
@@ -15,8 +15,8 @@ Gem::Specification.new do |s|
15
15
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
16
  s.require_paths = ["lib"]
17
17
 
18
- s.add_dependency "motion-cocoapods", ">= 1.4.1"
18
+ s.add_dependency "motion-cocoapods", ">= 1.9.1"
19
19
  s.add_dependency "motion-require", ">= 0.1"
20
20
  s.add_development_dependency 'rake'
21
- s.add_development_dependency 'webstub', "~> 1.1"
21
+ s.add_development_dependency 'webstub', "~> 1.1.6"
22
22
  end
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # AFMotion
2
2
 
3
- [![Build Status](https://travis-ci.org/clayallsopp/afmotion.png?branch=master)](https://travis-ci.org/clayallsopp/afmotion)
3
+ [![Build Status](https://travis-ci.org/clayallsopp/afmotion.png?branch=master)](https://travis-ci.org/clayallsopp/afmotion) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fclayallsopp%2Fafmotion.svg?size=small)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fclayallsopp%2Fafmotion?ref=badge_small)
4
4
 
5
- AFMotion is a thin RubyMotion wrapper for [AFNetworking](https://github.com/AFNetworking/AFNetworking), the absolute best networking library on iOS.
5
+ AFMotion is a thin RubyMotion wrapper for [AFNetworking](https://github.com/AFNetworking/AFNetworking), the absolute best networking library on iOS and OS X.
6
6
 
7
7
  ## Usage
8
8
 
@@ -33,32 +33,45 @@ end
33
33
  end
34
34
  ```
35
35
 
36
- You can either use `AFMotion::Client` or `AFMotion::SessionClient` to group similar requests. They have identical APIs, except for their creation and that their request `result` objects contain either `result.operation` (for `::Client`) or `result.task` (for `::SessionClient`).
36
+ #### Migration from AFMotion 2.x
37
37
 
38
- #### AFMotion::Client
38
+ _Breaking Change_
39
+ Parameters must now be specified with the `params:` keyword arg.
39
40
 
40
- If you're interacting with a web service, you can use [`AFHTTPRequestOperationManager`](http://cocoadocs.org/docsets/AFNetworking/2.0.0/Classes/AFHTTPRequestOperationManager.html) with this nice wrapper:
41
+ AFMotion 2.x
41
42
 
42
43
  ```ruby
43
- # DSL Mapping to properties of AFHTTPRequestOperationManager
44
+ AFMotion::HTTP.get("http://google.com", q: "rubymotion") do |result|
45
+ # sends request to http://google.com?q=rubymotion
46
+ end
47
+ ```
44
48
 
45
- @client = AFMotion::Client.build("https://alpha-api.app.net/") do
46
- header "Accept", "application/json"
49
+ AFMotion 3.x
47
50
 
48
- response_serializer :json
51
+ ```ruby
52
+ AFMotion::HTTP.get("http://google.com", params: { q: "rubymotion" }) do |result|
53
+ # sends request to http://google.com?q=rubymotion
49
54
  end
50
55
  ```
51
56
 
52
- #### AFMotion::SessionClient
53
-
54
- If you're using iOS7, you can use [`AFHTTPSessionManager`](http://cocoadocs.org/docsets/AFNetworking/2.0.0/Classes/AFHTTPSessionManager.html):
57
+ This allows you to also pass in a progress_block or additional headers on the fly:
55
58
 
56
59
  ```ruby
57
- # DSL Mapping to properties of AFHTTPSessionManager
60
+ AFMotion::HTTP.get("http://url.com/large_file.mov", params: { quality: "high" }, progress_block: proc { |progress| update_progress(progress) }, headers: {}) do |result|
61
+ # sends request to http://google.com?q=rubymotion
62
+ end
63
+ ```
58
64
 
59
- @client = AFMotion::SessionClient.build("https://alpha-api.app.net/") do
60
- session_configuration :default
65
+ For grouping similar requests (AFHTTPSession), use `AFMotion::Client` (now exactly the same as `AFMotion::SessionClient`)
61
66
 
67
+ #### AFMotion::Client
68
+
69
+ If you're interacting with a web service, you can use [`AFHTTPRequestOperationManager`](http://cocoadocs.org/docsets/AFNetworking/2.0.0/Classes/AFHTTPRequestOperationManager.html) with this nice wrapper:
70
+
71
+ ```ruby
72
+ # DSL Mapping to properties of AFHTTPRequestOperationManager
73
+
74
+ @client = AFMotion::Client.build("https://alpha-api.app.net/") do
62
75
  header "Accept", "application/json"
63
76
 
64
77
  response_serializer :json
@@ -103,8 +116,7 @@ Each AFMotion wrapper callback yields an `AFMotion::HTTPResult` object. This obj
103
116
 
104
117
  ```ruby
105
118
  AFMotion::some_function do |result|
106
- # result.operation is the AFURLConnectionOperation instance
107
- p result.operation.inspect
119
+ p result.task.inspect
108
120
  p result.status_code
109
121
 
110
122
  if result.success?
@@ -135,7 +147,7 @@ end
135
147
  Example:
136
148
 
137
149
  ```ruby
138
- AFMotion::HTTP.get("http://google.com", q: "rubymotion") do |result|
150
+ AFMotion::HTTP.get("http://google.com", params: { q: "rubymotion" }) do |result|
139
151
  # sends request to http://google.com?q=rubymotion
140
152
  end
141
153
  ```
@@ -148,7 +160,7 @@ end
148
160
 
149
161
  ### HTTP Client
150
162
 
151
- If you're constantly accesing a web service, it's a good idea to use an `AFHTTPRequestOperationManager`. Things lets you add a common base URL and request headers to all the requests issued through it, like so:
163
+ If you're constantly accesing a web service, it's a good idea to use an `AFHTTPSessionManager`. Things lets you add a common base URL and request headers to all the requests issued through it, like so:
152
164
 
153
165
  ```ruby
154
166
  client = AFMotion::Client.build("https://alpha-api.app.net/") do
@@ -163,42 +175,23 @@ client.get("stream/0/posts/stream/global") do |result|
163
175
  end
164
176
  ```
165
177
 
166
- If you're using iOS7, you can use [`AFHTTPSessionManager`](http://cocoadocs.org/docsets/AFNetworking/2.0.0/Classes/AFHTTPSessionManager.html):
167
-
168
- ```ruby
169
- # DSL Mapping to properties of AFHTTPSessionManager
170
-
171
- client = AFMotion::SessionClient.build("https://alpha-api.app.net/") do
172
- session_configuration :default
173
-
174
- header "Accept", "application/json"
175
-
176
- response_serializer :json
177
- end
178
-
179
- client.get("stream/0/posts/stream/global") do |result|
180
- # result.task exists
181
- ...
182
- end
183
- ```
184
-
185
178
  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`.
186
179
 
187
180
  `AFHTTPRequestOperationManager` & `AFHTTPSessionManager` support methods of the form `Client#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:
188
181
 
189
182
  ```ruby
190
- client.get("users", id: 1) do |result|
183
+ client.get("users", params: { id: 1 }) do |result|
191
184
  ...
192
185
  end
193
186
 
194
- client.post("users", name: "@clayallsopp", library: "AFMotion") do |result|
187
+ client.post("users", params: { name: "@clayallsopp", library: "AFMotion" }) do |result|
195
188
  ...
196
189
  end
197
190
  ```
198
191
 
199
192
  #### Multipart Requests
200
193
 
201
- `AFHTTPRequestOperationManager` & `AFHTTPSessionManager` support multipart form requests (i.e. for image uploading) - simply use `multipart_post` and it'll convert your parameters into properly encoded multipart data. For all other types of request data, use the `form_data` object passed to your callback:
194
+ `AFHTTPSessionManager` support multipart form requests (i.e. for image uploading) - simply use `multipart_post` and it'll convert your parameters into properly encoded multipart data. For all other types of request data, use the `form_data` object passed to your callback:
202
195
 
203
196
  ```ruby
204
197
  # an instance of UIImage
@@ -220,17 +213,14 @@ end
220
213
 
221
214
  This is an instance of [`AFMultipartFormData`](http://cocoadocs.org/docsets/AFNetworking/2.0.0/Protocols/AFMultipartFormData.html).
222
215
 
223
- 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:
216
+ If you want to track upload progress, simply add a progress_block (Taking a single arg: `NSProgress`)
224
217
 
225
218
  ```ruby
226
- client.multipart_post("avatars") do |result, form_data, progress|
219
+ client.multipart_post("avatars", progress_block: proc { |progress| update_progress(progress) }) do |result, form_data|
227
220
  if form_data
228
221
  # Called before request runs
229
222
  # see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
230
223
  form_data.appendPartWithFileData(data, name: "avatar", fileName:"avatar.png", mimeType: "image/png")
231
- elsif progress
232
- # 0.0 < progress < 1.0
233
- my_widget.update_progress(progress)
234
224
  else
235
225
  ...
236
226
  end
@@ -273,3 +263,7 @@ client = AFMotion::SessionClient.build("https://alpha-api.app.net/") do |client|
273
263
  client.header "Accept", @custom_header
274
264
  end
275
265
  ```
266
+
267
+ ## License
268
+
269
+ [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fclayallsopp%2Fafmotion.svg?size=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fclayallsopp%2Fafmotion?ref=badge_large)
data/Rakefile CHANGED
@@ -1,7 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  $:.unshift("/Library/RubyMotion/lib")
3
+ $:.unshift("~/.rubymotion/rubymotion-templates") # Add this line
4
+ require 'motion/project/template/gem/gem_tasks'
3
5
  require 'motion/project/template/ios'
4
- require "bundler/gem_tasks"
5
6
  require "bundler/setup"
6
7
  Bundler.require :default
7
8
 
@@ -13,5 +14,5 @@ require 'webstub'
13
14
  Motion::Project::App.setup do |app|
14
15
  # Use `rake config' to see complete project settings.
15
16
  app.name = 'AFMotion'
16
- app.deployment_target = "7.1"
17
+ app.deployment_target = "10.0"
17
18
  end
@@ -16,6 +16,6 @@ Motion::Project::App.setup do |app|
16
16
  end
17
17
 
18
18
  app.pods do
19
- pod 'AFNetworking', '~> 2.5.0'
19
+ pod 'AFNetworking', '~> 4.0.0'
20
20
  end
21
21
  end
@@ -1,31 +1,4 @@
1
1
  module AFMotion
2
- # ported from https://github.com/AFNetworking/AFNetworking/blob/master/UIKit%2BAFNetworking/UIProgressView%2BAFNetworking.m
3
- class SessionObserver
4
-
5
- def initialize(task, callback)
6
- @callback = callback
7
- task.addObserver(self, forKeyPath:"state", options:0, context:nil)
8
- task.addObserver(self, forKeyPath:"countOfBytesSent", options:0, context:nil)
9
- end
10
-
11
- def observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
12
- if keyPath == "countOfBytesSent"
13
- # Could be -1, see https://github.com/AFNetworking/AFNetworking/issues/1354
14
- expectation = (object.countOfBytesExpectedToSend > 0) ? object.countOfBytesExpectedToSend.to_f : nil
15
- @callback.call(nil, object.countOfBytesSent.to_f, expectation)
16
- end
17
-
18
- if keyPath == "state" && object.state == NSURLSessionTaskStateCompleted
19
- begin
20
- object.removeObserver(self, forKeyPath: "state")
21
- object.removeObserver(self, forKeyPath: "countOfBytesSent")
22
- @callback = nil
23
- rescue
24
- end
25
- end
26
- end
27
- end
28
-
29
2
  module ClientShared
30
3
  def headers
31
4
  requestSerializer.headers
@@ -39,29 +12,25 @@ module AFMotion
39
12
  requestSerializer.authorization = authorization
40
13
  end
41
14
 
42
- def multipart_post(path, parameters = {}, &callback)
43
- create_multipart_operation(:post, path, parameters, &callback)
15
+ def multipart_post(path, options = {}, &callback)
16
+ create_multipart_task(:post, path, options, &callback)
44
17
  end
45
18
 
46
- def multipart_put(path, parameters = {}, &callback)
47
- create_multipart_operation(:put, path, parameters, &callback)
19
+ def multipart_put(path, options = {}, &callback)
20
+ create_multipart_task(:put, path, options, &callback)
48
21
  end
49
22
 
50
- def create_multipart_operation(http_method, path, parameters = {}, &callback)
51
- inner_callback = Proc.new do |result, form_data, bytes_written_now, total_bytes_written, total_bytes_expect|
23
+ def create_multipart_task(http_method, path, options = {}, &callback)
24
+ parameters = options[:params]
25
+ headers = options.fetch(:headers, {})
26
+ progress = options[:progress_block]
27
+
28
+ inner_callback = Proc.new do |result, form_data|
52
29
  case callback.arity
53
30
  when 1
54
31
  callback.call(result)
55
32
  when 2
56
33
  callback.call(result, form_data)
57
- when 3
58
- progress = nil
59
- if total_bytes_written && total_bytes_expect
60
- progress = total_bytes_written.to_f / total_bytes_expect.to_f
61
- end
62
- callback.call(result, form_data, progress)
63
- when 5
64
- callback.call(result, form_data, bytes_written_now, total_bytes_written, total_bytes_expect)
65
34
  end
66
35
  end
67
36
 
@@ -72,62 +41,77 @@ module AFMotion
72
41
  }
73
42
  end
74
43
 
75
- upload_callback = nil
76
- if callback.arity > 2
77
- upload_callback = lambda { |bytes_written_now, total_bytes_written, total_bytes_expect|
78
- inner_callback.call(nil, nil, bytes_written_now, total_bytes_written, total_bytes_expect)
79
- }
80
- end
81
-
82
44
  http_method = http_method.to_s.upcase
83
45
  if http_method == "POST"
84
- operation_or_task = self.POST(path,
46
+ task = self.POST(path,
85
47
  parameters: parameters,
48
+ headers: headers,
86
49
  constructingBodyWithBlock: multipart_callback,
87
- success: AFMotion::Operation.success_block_for_http_method(:post, inner_callback),
88
- failure: AFMotion::Operation.failure_block(inner_callback))
50
+ progress: progress,
51
+ success: success_block_for_http_method(:post, inner_callback),
52
+ failure: failure_block(inner_callback))
89
53
  else
90
- operation_or_task = self.PUT(path,
54
+ task = self.PUT(path,
91
55
  parameters: parameters,
56
+ headers: headers,
92
57
  constructingBodyWithBlock: multipart_callback,
93
- success: AFMotion::Operation.success_block_for_http_method(:post, inner_callback),
94
- failure: AFMotion::Operation.failure_block(inner_callback))
58
+ progress: progress,
59
+ success: success_block_for_http_method(:post, inner_callback),
60
+ failure: failure_block(inner_callback))
95
61
  end
96
- if upload_callback
97
- if operation_or_task.is_a?(AFURLConnectionOperation)
98
- operation_or_task.setUploadProgressBlock(upload_callback)
99
- else
100
- # using NSURLSession - messy, probably leaks
101
- @observer = SessionObserver.new(operation_or_task, upload_callback)
102
- end
62
+ task
63
+ end
64
+
65
+ def create_task(http_method, path, options = {}, &callback)
66
+ parameters = options.fetch(:params, {})
67
+ headers = options.fetch(:headers, {})
68
+ progress = options[:progress_block]
69
+
70
+ method_signature = "#{http_method.to_s.upcase}:parameters:headers:progress:success:failure"
71
+ success = success_block_for_http_method(http_method, callback)
72
+ failure = failure_block(callback)
73
+ method_and_args = [method_signature, path, parameters, headers, progress, success, failure]
74
+
75
+ # HEAD doesn't take a progress arg
76
+ if http_method.to_s.upcase == "HEAD"
77
+ method_signature.gsub!("progress:", "")
78
+ method_and_args.delete_at(4)
103
79
  end
104
- operation_or_task
80
+
81
+ self.public_send(*method_and_args)
105
82
  end
106
83
 
107
- def create_operation(http_method, path, parameters = {}, &callback)
108
- method_signature = "#{http_method.upcase}:parameters:success:failure:"
109
- method = self.method(method_signature)
110
- success_block = AFMotion::Operation.success_block_for_http_method(http_method, callback)
111
- failure_block = AFMotion::Operation.failure_block(callback)
112
- operation = method.call(path, parameters, success_block, failure_block)
113
- if parameters && parameters[:progress_block] && operation.respond_to?(:setDownloadProgressBlock)
114
- operation.setDownloadProgressBlock(parameters.delete(:progress_block))
84
+ def success_block_for_http_method(http_method, callback)
85
+ if http_method.downcase.to_sym == :head
86
+ return ->(task) {
87
+ result = AFMotion::HTTPResult.new(task, nil, nil)
88
+ callback.call(result)
89
+ }
115
90
  end
116
- operation
91
+
92
+ ->(task, responseObject) {
93
+ result = AFMotion::HTTPResult.new(task, responseObject, nil)
94
+ callback.call(result)
95
+ }
117
96
  end
118
97
 
119
- alias_method :create_task, :create_operation
98
+ def failure_block(callback)
99
+ ->(task, error) {
100
+ result = AFMotion::HTTPResult.new(task, nil, error)
101
+ callback.call(result)
102
+ }
103
+ end
120
104
 
121
105
  private
122
106
  # To force RubyMotion pre-compilation of these methods
123
107
  def dummy
124
- self.GET("", parameters: nil, success: nil, failure: nil)
125
- self.HEAD("", parameters: nil, success: nil, failure: nil)
126
- self.POST("", parameters: nil, success: nil, failure: nil)
127
- self.POST("", parameters: nil, constructingBodyWithBlock: nil, success: nil, failure: nil)
128
- self.PUT("", parameters: nil, success: nil, failure: nil)
129
- self.DELETE("", parameters: nil, success: nil, failure: nil)
130
- self.PATCH("", parameters: nil, success: nil, failure: nil)
108
+ self.GET("", parameters: nil, headers: nil, progress: nil, success: nil, failure: nil)
109
+ self.HEAD("", parameters: nil, headers: nil, success: nil, failure: nil)
110
+ self.POST("", parameters: nil, headers: nil, progress: nil, success: nil, failure: nil)
111
+ self.POST("", parameters: nil, headers: nil, constructingBodyWithBlock: nil, progress: nil, success: nil, failure: nil)
112
+ self.PUT("", parameters: nil, headers: nil, progress: nil, success: nil, failure: nil)
113
+ self.DELETE("", parameters: nil, headers: nil, progress: nil, success: nil, failure: nil)
114
+ self.PATCH("", parameters: nil, headers: nil, progress: nil, success: nil, failure: nil)
131
115
  end
132
116
  end
133
117
  end
@@ -0,0 +1,73 @@
1
+ motion_require '../client_shared'
2
+
3
+ module AFMotion
4
+ module Serialization
5
+ def with_request_serializer(serializer_klass)
6
+ self.requestSerializer = serializer_klass.serializer
7
+ self
8
+ end
9
+
10
+ def with_response_serializer(serializer_klass)
11
+ self.responseSerializer = serializer_klass.serializer
12
+ self
13
+ end
14
+
15
+ def http!
16
+ with_request_serializer(AFHTTPRequestSerializer).
17
+ with_response_serializer(AFHTTPResponseSerializer)
18
+ end
19
+
20
+ def json!
21
+ with_request_serializer(AFJSONRequestSerializer).
22
+ with_response_serializer(AFJSONResponseSerializer)
23
+ end
24
+
25
+ def xml!
26
+ with_response_serializer(AFXMLParserResponseSerializer)
27
+ end
28
+
29
+ def plist!
30
+ with_request_serializer(AFPropertyListRequestSerializer).
31
+ with_response_serializer(AFPropertyListResponseSerializer)
32
+ end
33
+
34
+ def image!
35
+ with_response_serializer(AFImageResponseSerializer)
36
+ end
37
+ end
38
+ end
39
+
40
+ class AFHTTPSessionManager
41
+ include AFMotion::Serialization
42
+ include AFMotion::ClientShared
43
+
44
+ AFMotion::HTTP_METHODS.each do |method|
45
+ # EX client.get('my/resource.json')
46
+ define_method "#{method}", -> (path, options = {}, &callback) do
47
+ create_task(method, path, options, &callback)
48
+ end
49
+ end
50
+
51
+ # options = {parameters: , constructingBodyWithBlock: , success:, failure:}
52
+ def PUT(url_string, options = {})
53
+ parameters = options[:parameters]
54
+ block = options[:constructingBodyWithBlock]
55
+ progress = options[:progress_block]
56
+ success = options[:success]
57
+ failure = options[:failure]
58
+
59
+ request = self.requestSerializer.multipartFormRequestWithMethod("PUT", URLString: NSURL.URLWithString(url_string, relativeToURL: self.baseURL).absoluteString, parameters:parameters, constructingBodyWithBlock:block, error:nil)
60
+
61
+ task = self.dataTaskWithRequest(request, uploadProgress: progress, downloadProgress: nil, completionHandler: ->(response, responseObject, error) {
62
+ if error && failure
63
+ failure.call(task, error)
64
+ elsif success
65
+ success.call(task, responseObject)
66
+ end
67
+ })
68
+
69
+ task.resume
70
+
71
+ task
72
+ end
73
+ end