afmotion 2.0.0.rc1 → 2.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/Gemfile.lock +2 -2
- data/README.md +2 -0
- data/lib/afmotion/client_shared.rb +54 -17
- data/lib/afmotion/http_client.rb +13 -46
- data/lib/afmotion/http_result.rb +1 -1
- data/lib/afmotion/operation.rb +7 -6
- data/lib/afmotion/session_client.rb +22 -0
- data/lib/afmotion/version.rb +1 -1
- data/lib/afmotion.rb +1 -1
- data/spec/http_client_spec.rb +40 -35
- data/spec/session_client_spec.rb +45 -36
- data/vendor/Podfile.lock +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b99324f4972198d794024d6f1446c7a1b0733efe
|
4
|
+
data.tar.gz: b6cfbfd89ec96194bef5267f0029259db873b14c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3712e2ceb4ac7973649c392692ba1df96c672b6cca7562a552f2f4241a53f901bda3daeff7b30453eff8e044184767ab02e4db037d85a6d93355816654951f13
|
7
|
+
data.tar.gz: 317faec654548c60b2eb1c83e551e6399dc60e05cf89843cc5ce4f3b431f68477410efe8aba8622b61c26db9b6b36e8ba90f53ad12bd7a754305b97790b8908d
|
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
afmotion (2.0.0.
|
4
|
+
afmotion (2.0.0.rc2)
|
5
5
|
motion-cocoapods (~> 1.4.0)
|
6
6
|
motion-require (~> 0.0.7)
|
7
7
|
|
@@ -30,7 +30,7 @@ GEM
|
|
30
30
|
colored (1.2)
|
31
31
|
escape (0.0.4)
|
32
32
|
i18n (0.6.5)
|
33
|
-
json (1.8.
|
33
|
+
json (1.8.1)
|
34
34
|
motion-cocoapods (1.4.0)
|
35
35
|
cocoapods (>= 0.26.2)
|
36
36
|
motion-require (0.0.7)
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# AFMotion
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/usepropeller/afmotion.png?branch=master)](https://travis-ci.org/usepropeller/afmotion)
|
4
|
+
|
3
5
|
AFMotion is a thin RubyMotion wrapper for [AFNetworking](https://github.com/AFNetworking/AFNetworking), the absolute best networking library on iOS.
|
4
6
|
|
5
7
|
## Usage
|
@@ -1,4 +1,30 @@
|
|
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
|
+
# I've only seen this be -1, so callback might not get called
|
13
|
+
if keyPath == "countOfBytesSent" && object.countOfBytesExpectedToSend > 0
|
14
|
+
@callback.call(nil, object.countOfBytesSent.to_f, object.countOfBytesExpectedToSend.to_f)
|
15
|
+
end
|
16
|
+
|
17
|
+
if keyPath == "state" && object.state == NSURLSessionTaskStateCompleted
|
18
|
+
begin
|
19
|
+
object.removeObserver(self, forKeyPath: "state")
|
20
|
+
object.removeObserver(self, forKeyPath: "countOfBytesSent")
|
21
|
+
@callback = nil
|
22
|
+
rescue
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
2
28
|
module ClientShared
|
3
29
|
def headers
|
4
30
|
requestSerializer.headers
|
@@ -13,13 +39,15 @@ module AFMotion
|
|
13
39
|
end
|
14
40
|
|
15
41
|
def multipart_post(path, parameters = {}, &callback)
|
16
|
-
create_multipart_operation(path, parameters, &callback)
|
42
|
+
create_multipart_operation(:post, path, parameters, &callback)
|
17
43
|
end
|
18
44
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
45
|
+
def multipart_put(path, parameters = {}, &callback)
|
46
|
+
create_multipart_operation(:put, path, parameters, &callback)
|
47
|
+
end
|
22
48
|
|
49
|
+
def create_multipart_operation(http_method, path, parameters = {}, &callback)
|
50
|
+
inner_callback = Proc.new do |result, form_data, bytes_written_now, total_bytes_written, total_bytes_expect|
|
23
51
|
case callback.arity
|
24
52
|
when 1
|
25
53
|
callback.call(result)
|
@@ -37,7 +65,7 @@ module AFMotion
|
|
37
65
|
end
|
38
66
|
|
39
67
|
multipart_callback = nil
|
40
|
-
if callback.arity
|
68
|
+
if callback.arity > 1
|
41
69
|
multipart_callback = lambda { |formData|
|
42
70
|
inner_callback.call(nil, formData)
|
43
71
|
}
|
@@ -50,20 +78,29 @@ module AFMotion
|
|
50
78
|
}
|
51
79
|
end
|
52
80
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
81
|
+
http_method = http_method.to_s.upcase
|
82
|
+
if http_method == "POST"
|
83
|
+
operation_or_task = self.POST(path,
|
84
|
+
parameters: parameters,
|
85
|
+
constructingBodyWithBlock: multipart_callback,
|
86
|
+
success: AFMotion::Operation.success_block_for_http_method(:post, inner_callback),
|
87
|
+
failure: AFMotion::Operation.failure_block(inner_callback))
|
88
|
+
else
|
89
|
+
operation_or_task = self.PUT(path,
|
90
|
+
parameters: parameters,
|
91
|
+
constructingBodyWithBlock: multipart_callback,
|
92
|
+
success: AFMotion::Operation.success_block_for_http_method(:pust, inner_callback),
|
93
|
+
failure: AFMotion::Operation.failure_block(inner_callback))
|
94
|
+
end
|
63
95
|
if upload_callback
|
64
|
-
|
96
|
+
if operation_or_task.is_a?(AFURLConnectionOperation)
|
97
|
+
operation_or_task.setUploadProgressBlock(upload_callback)
|
98
|
+
else
|
99
|
+
# using NSURLSession - messy, probably leaks
|
100
|
+
@observer = SessionObserver.new(operation_or_task, upload_callback)
|
101
|
+
end
|
65
102
|
end
|
66
|
-
|
103
|
+
operation_or_task
|
67
104
|
end
|
68
105
|
|
69
106
|
def create_operation(http_method, path, parameters = {}, &callback)
|
data/lib/afmotion/http_client.rb
CHANGED
@@ -79,52 +79,6 @@ module AFMotion
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
# TODO: remove this when/if https://github.com/AFNetworking/AFNetworking/issues/1388 resolved
|
83
|
-
module AFMotion
|
84
|
-
module QueryPairHelper
|
85
|
-
module_function
|
86
|
-
|
87
|
-
def af_QueryStringPairsFromDictionary(dictionary)
|
88
|
-
af_QueryStringPairsFromKeyAndValue(nil, dictionary)
|
89
|
-
end
|
90
|
-
|
91
|
-
def af_QueryStringPairsFromKeyAndValue(key, value)
|
92
|
-
mutableQueryStringComponents = []
|
93
|
-
if value.is_a?(NSDictionary)
|
94
|
-
sortDescriptor = NSSortDescriptor.sortDescriptorWithKey("description", ascending: true, selector:'caseInsensitiveCompare:')
|
95
|
-
value.allKeys.sortedArrayUsingDescriptors([sortDescriptor]).each do |nestedKey|
|
96
|
-
nestedValue = value[nestedKey]
|
97
|
-
if nestedValue
|
98
|
-
mutableQueryStringComponents += af_QueryStringPairsFromKeyAndValue(key ? "#{key}[#{nestedKey}]" : nestedKey, nestedValue)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
elsif value.is_a?(NSArray)
|
102
|
-
value.each do |obj|
|
103
|
-
mutableQueryStringComponents += af_QueryStringPairsFromKeyAndValue(key, obj)
|
104
|
-
end
|
105
|
-
elsif value.is_a?(NSSet)
|
106
|
-
value.each do |obj|
|
107
|
-
mutableQueryStringComponents += af_QueryStringPairsFromKeyAndValue(key, obj)
|
108
|
-
end
|
109
|
-
else
|
110
|
-
mutableQueryStringComponents << AFQueryStringPair.alloc.initWithField(key, value: value)
|
111
|
-
end
|
112
|
-
|
113
|
-
mutableQueryStringComponents
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
class MultipartParametersWrapper < Hash
|
118
|
-
def initialize(parameters)
|
119
|
-
super()
|
120
|
-
query_pairs = QueryPairHelper.af_QueryStringPairsFromDictionary(parameters)
|
121
|
-
query_pairs.each do |key_pair|
|
122
|
-
self[key_pair.field] = key_pair.value
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
82
|
class AFHTTPRequestOperationManager
|
129
83
|
include AFMotion::ClientShared
|
130
84
|
|
@@ -134,4 +88,17 @@ class AFHTTPRequestOperationManager
|
|
134
88
|
create_operation(method, path, parameters, &callback)
|
135
89
|
end
|
136
90
|
end
|
91
|
+
|
92
|
+
# options = {parameters: , constructingBodyWithBlock: , success:, failure:}
|
93
|
+
def PUT(url_string, options = {})
|
94
|
+
parameters = options[:parameters]
|
95
|
+
block = options[:constructingBodyWithBlock]
|
96
|
+
success = options[:success]
|
97
|
+
failure = options[:failure]
|
98
|
+
request = self.requestSerializer.multipartFormRequestWithMethod("PUT", URLString: NSURL.URLWithString(url_string, relativeToURL:self.baseURL).absoluteString, parameters: parameters, constructingBodyWithBlock:block)
|
99
|
+
operation = self.HTTPRequestOperationWithRequest(request, success:success, failure:failure)
|
100
|
+
self.operationQueue.addOperation(operation)
|
101
|
+
|
102
|
+
operation
|
103
|
+
end
|
137
104
|
end
|
data/lib/afmotion/http_result.rb
CHANGED
@@ -3,7 +3,7 @@ module AFMotion
|
|
3
3
|
attr_accessor :operation, :object, :error, :task
|
4
4
|
|
5
5
|
def initialize(operation_or_task, responseObject, error)
|
6
|
-
if operation_or_task.is_a?(NSURLSessionTask) ||
|
6
|
+
if defined?(NSURLSessionTask) && operation_or_task.is_a?(NSURLSessionTask) ||
|
7
7
|
# cluser class ugh
|
8
8
|
operation_or_task.class.to_s.include?("Task")
|
9
9
|
self.task = operation_or_task
|
data/lib/afmotion/operation.rb
CHANGED
@@ -10,20 +10,21 @@ module AFMotion
|
|
10
10
|
|
11
11
|
def success_block_for_http_method(http_method, callback)
|
12
12
|
if http_method.downcase.to_sym == :head
|
13
|
-
return lambda { |
|
14
|
-
AFMotion::HTTPResult.new(
|
13
|
+
return lambda { |operation_or_task|
|
14
|
+
AFMotion::HTTPResult.new(operation_or_task, nil, nil)
|
15
15
|
}
|
16
16
|
end
|
17
17
|
|
18
|
-
lambda { |
|
19
|
-
result = AFMotion::HTTPResult.new(
|
18
|
+
lambda { |operation_or_task, responseObject|
|
19
|
+
result = AFMotion::HTTPResult.new(operation_or_task, responseObject, nil)
|
20
20
|
callback.call(result)
|
21
21
|
}
|
22
22
|
end
|
23
23
|
|
24
24
|
def failure_block(callback)
|
25
|
-
lambda { |
|
26
|
-
|
25
|
+
lambda { |operation_or_task, error|
|
26
|
+
response_object = operation_or_task.is_a?(AFHTTPRequestOperation) ? operation_or_task.responseObject : nil
|
27
|
+
result = AFMotion::HTTPResult.new(operation_or_task, response_object, error)
|
27
28
|
callback.call(result)
|
28
29
|
}
|
29
30
|
end
|
@@ -125,4 +125,26 @@ class AFHTTPSessionManager
|
|
125
125
|
create_task(method, path, parameters, &callback)
|
126
126
|
end
|
127
127
|
end
|
128
|
+
|
129
|
+
# options = {parameters: , constructingBodyWithBlock: , success:, failure:}
|
130
|
+
def PUT(url_string, options = {})
|
131
|
+
parameters = options[:parameters]
|
132
|
+
block = options[:constructingBodyWithBlock]
|
133
|
+
success = options[:success]
|
134
|
+
failure = options[:failure]
|
135
|
+
|
136
|
+
request = self.requestSerializer.multipartFormRequestWithMethod("PUT", URLString: NSURL.URLWithString(url_string, relativeToURL: self.baseURL).absoluteString, parameters:parameters, constructingBodyWithBlock:block)
|
137
|
+
|
138
|
+
task = self.dataTaskWithRequest(request, completionHandler: ->(response, responseObject, error) {
|
139
|
+
if error && failure
|
140
|
+
failure.call(task, error)
|
141
|
+
elsif success
|
142
|
+
success.call(task, responseObject)
|
143
|
+
end
|
144
|
+
})
|
145
|
+
|
146
|
+
task.resume
|
147
|
+
|
148
|
+
task
|
149
|
+
end
|
128
150
|
end
|
data/lib/afmotion/version.rb
CHANGED
data/lib/afmotion.rb
CHANGED
data/spec/http_client_spec.rb
CHANGED
@@ -131,50 +131,55 @@ describe "AFHTTPClient" do
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
@
|
138
|
-
|
139
|
-
|
134
|
+
["multipart_post", "multipart_put"].each do |multipart_method|
|
135
|
+
describe "##{multipart_method}" do
|
136
|
+
it "should trigger multipart request" do
|
137
|
+
@client.send(multipart_method, "", test: "Herp") do |result, form_data|
|
138
|
+
@result = result
|
139
|
+
resume if result
|
140
|
+
end
|
140
141
|
|
141
|
-
|
142
|
-
|
143
|
-
|
142
|
+
wait_max(10) do
|
143
|
+
@result.should.not == nil
|
144
|
+
@result.operation.request.valueForHTTPHeaderField("Content-Type").include?("multipart/form-data").should == true
|
145
|
+
end
|
144
146
|
end
|
145
|
-
end
|
146
147
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
148
|
+
it "should work with form data" do
|
149
|
+
@client.send(multipart_method, "", test: "Herp") do |result, form_data|
|
150
|
+
if result
|
151
|
+
resume
|
152
|
+
else
|
153
|
+
@form_data = form_data
|
154
|
+
end
|
153
155
|
end
|
154
|
-
end
|
155
156
|
|
156
|
-
|
157
|
-
|
157
|
+
wait_max(10) do
|
158
|
+
@form_data.should.not == nil
|
159
|
+
end
|
158
160
|
end
|
159
|
-
end
|
160
161
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
form_data
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
162
|
+
it "should have upload callback with raw progress" do
|
163
|
+
image = UIImage.imageNamed("test")
|
164
|
+
@data = UIImagePNGRepresentation(image)
|
165
|
+
@file_added = false
|
166
|
+
@client = AFHTTPRequestOperationManager.alloc.initWithBaseURL("http://bing.com/".to_url)
|
167
|
+
@client.send(multipart_method, "", test: "Herp") do |result, form_data, progress|
|
168
|
+
if form_data
|
169
|
+
@file_added = true
|
170
|
+
form_data.appendPartWithFileData(@data, name: "test", fileName:"test.png", mimeType: "image/png")
|
171
|
+
elsif progress
|
172
|
+
@progress ||= progress
|
173
|
+
elsif result
|
174
|
+
resume
|
175
|
+
end
|
172
176
|
end
|
173
|
-
end
|
174
177
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
+
wait_max(20) do
|
179
|
+
@file_added.should == true
|
180
|
+
@progress.should <= 1.0
|
181
|
+
@progress.should.not == nil
|
182
|
+
end
|
178
183
|
end
|
179
184
|
end
|
180
185
|
end
|
data/spec/session_client_spec.rb
CHANGED
@@ -105,7 +105,7 @@ end
|
|
105
105
|
|
106
106
|
describe "AFHTTPSessionManager" do
|
107
107
|
before do
|
108
|
-
@client = AFHTTPSessionManager.alloc.initWithBaseURL("http://
|
108
|
+
@client = AFHTTPSessionManager.alloc.initWithBaseURL("http://bing.com/".to_url,
|
109
109
|
sessionConfiguration: NSURLSessionConfiguration.defaultSessionConfiguration)
|
110
110
|
end
|
111
111
|
|
@@ -167,50 +167,59 @@ describe "AFHTTPSessionManager" do
|
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
-
describe "#multipart_post" do
|
171
|
-
it "should trigger multipart request" do
|
172
|
-
@client.multipart_post("", test: "Herp") do |result, form_data|
|
173
|
-
@result = result
|
174
|
-
resume if result
|
175
|
-
end
|
176
170
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
171
|
+
["multipart_post", "multipart_put"].each do |multipart_method|
|
172
|
+
describe "##{multipart_method}" do
|
173
|
+
it "should trigger multipart request" do
|
174
|
+
@client.send(multipart_method, "", test: "Herp") do |result, form_data|
|
175
|
+
@result = result
|
176
|
+
resume if result
|
177
|
+
end
|
182
178
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
resume
|
187
|
-
else
|
188
|
-
@form_data = form_data
|
179
|
+
wait_max(10) do
|
180
|
+
@result.should.not == nil
|
181
|
+
@result.task.currentRequest.valueForHTTPHeaderField("Content-Type").include?("multipart/form-data").should == true
|
189
182
|
end
|
190
183
|
end
|
191
184
|
|
192
|
-
|
193
|
-
@
|
194
|
-
|
195
|
-
|
185
|
+
it "should work with form data" do
|
186
|
+
@client.send(multipart_method, "", test: "Herp") do |result, form_data|
|
187
|
+
if result
|
188
|
+
resume
|
189
|
+
else
|
190
|
+
@form_data = form_data
|
191
|
+
end
|
192
|
+
end
|
196
193
|
|
197
|
-
|
198
|
-
|
199
|
-
@data = UIImagePNGRepresentation(image)
|
200
|
-
@client = AFHTTPRequestOperationManager.alloc.initWithBaseURL("http://bing.com/".to_url)
|
201
|
-
@client.multipart_post("", test: "Herp") do |result, form_data, progress|
|
202
|
-
if form_data
|
203
|
-
form_data.appendPartWithFileData(@data, name: "test", fileName:"test.png", mimeType: "image/png")
|
204
|
-
elsif progress
|
205
|
-
@progress ||= progress
|
206
|
-
elsif result
|
207
|
-
resume
|
194
|
+
wait_max(10) do
|
195
|
+
@form_data.should.not == nil
|
208
196
|
end
|
209
197
|
end
|
210
198
|
|
211
|
-
|
212
|
-
|
213
|
-
@
|
199
|
+
it "should have upload callback with raw progress" do
|
200
|
+
image = UIImage.imageNamed("test")
|
201
|
+
@data = UIImagePNGRepresentation(image)
|
202
|
+
@file_added = nil
|
203
|
+
@client.send(multipart_method, "", test: "Herp") do |result, form_data, progress|
|
204
|
+
if form_data
|
205
|
+
@file_added = true
|
206
|
+
form_data.appendPartWithFileData(@data, name: "test", fileName:"test.png", mimeType: "image/png")
|
207
|
+
elsif progress
|
208
|
+
@progress ||= progress
|
209
|
+
elsif result
|
210
|
+
@result = result
|
211
|
+
resume
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
wait_max(20) do
|
216
|
+
@file_added.should == true
|
217
|
+
if (UIDevice.currentDevice.model =~ /simulator/i).nil?
|
218
|
+
@progress.should <= 1.0
|
219
|
+
@progress.should.not == nil
|
220
|
+
end
|
221
|
+
@result.should.not == nil
|
222
|
+
end
|
214
223
|
end
|
215
224
|
end
|
216
225
|
end
|
data/vendor/Podfile.lock
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: afmotion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Clay Allsopp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10
|
11
|
+
date: 2013-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: motion-cocoapods
|
@@ -60,6 +60,7 @@ extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
62
|
- .gitignore
|
63
|
+
- .travis.yml
|
63
64
|
- AFMotion.gemspec
|
64
65
|
- Gemfile
|
65
66
|
- Gemfile.lock
|