afmotion 2.0.0.rc1 → 2.0.0.rc2
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 +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
|
+
[](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
|