bubble-wrap 1.2.0 → 1.3.0.osx
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 +8 -8
- data/CHANGELOG.md +4 -2
- data/Gemfile.lock +1 -1
- data/README.md +217 -7
- data/Rakefile +23 -2
- data/lib/bubble-wrap/camera.rb +10 -6
- data/lib/bubble-wrap/core.rb +14 -1
- data/lib/bubble-wrap/ext/motion_project_app.rb +8 -0
- data/lib/bubble-wrap/font.rb +3 -1
- data/lib/bubble-wrap/http.rb +2 -0
- data/lib/bubble-wrap/loader.rb +17 -2
- data/lib/bubble-wrap/location.rb +9 -6
- data/lib/bubble-wrap/media.rb +10 -6
- data/lib/bubble-wrap/test.rb +6 -1
- data/lib/bubble-wrap/ui.rb +5 -2
- data/lib/bubble-wrap/version.rb +2 -7
- data/motion/core.rb +6 -1
- data/motion/core/app.rb +3 -64
- data/motion/core/device.rb +0 -55
- data/motion/core/device/{camera.rb → ios/camera.rb} +0 -0
- data/motion/core/device/{camera_wrapper.rb → ios/camera_wrapper.rb} +0 -0
- data/motion/core/device/ios/screen.rb +75 -0
- data/motion/core/device/osx/screen.rb +18 -0
- data/motion/core/device/screen.rb +1 -69
- data/motion/core/ios/app.rb +71 -0
- data/motion/core/ios/device.rb +59 -0
- data/motion/core/osx/app.rb +15 -0
- data/motion/core/osx/device.rb +6 -0
- data/motion/core/string.rb +3 -2
- data/motion/http.rb +0 -364
- data/motion/http/query.rb +367 -0
- data/motion/http/response.rb +32 -0
- data/motion/test_suite_delegate.rb +58 -0
- data/motion/ui/ui_alert_view.rb +169 -0
- data/motion/ui/ui_bar_button_item.rb +55 -53
- data/motion/util/constants.rb +34 -32
- data/samples/alert/.gitignore +16 -0
- data/samples/alert/Gemfile +3 -0
- data/samples/alert/Rakefile +10 -0
- data/samples/alert/app/app_delegate.rb +8 -0
- data/samples/alert/app/controllers/alert_view_controller.rb +74 -0
- data/samples/alert/resources/Default-568h@2x.png +0 -0
- data/samples/alert/spec/main_spec.rb +9 -0
- data/samples/media/.gitignore +16 -0
- data/samples/media/Rakefile +11 -0
- data/samples/media/app/app_delegate.rb +8 -0
- data/samples/media/app/controllers/play_controller.rb +46 -0
- data/samples/media/resources/Default-568h@2x.png +0 -0
- data/samples/media/resources/test.mp3 +0 -0
- data/samples/media/spec/main_spec.rb +9 -0
- data/samples/osx/Gemfile +3 -0
- data/samples/osx/Gemfile.lock +10 -0
- data/samples/osx/Rakefile +11 -0
- data/samples/osx/app/app_delegate.rb +69 -0
- data/samples/osx/app/menu.rb +108 -0
- data/samples/osx/resources/Credits.rtf +29 -0
- data/samples/osx/spec/main_spec.rb +9 -0
- data/spec/motion/core/app_spec.rb +5 -164
- data/spec/motion/core/device/{camera_spec.rb → ios/camera_spec.rb} +0 -0
- data/spec/motion/core/device/{camera_wrapper_spec.rb → ios/camera_wrapper_spec.rb} +0 -0
- data/spec/motion/core/device/ios/device_spec.rb +74 -0
- data/spec/motion/core/device/{screen_spec.rb → ios/screen_spec.rb} +2 -1
- data/spec/motion/core/device/osx/screen_spec.rb +26 -0
- data/spec/motion/core/device_spec.rb +0 -71
- data/spec/motion/core/ios/app_spec.rb +180 -0
- data/spec/motion/core/kvo_spec.rb +23 -7
- data/spec/motion/core/ns_index_path_spec.rb +10 -2
- data/spec/motion/core/osx/app_spec.rb +15 -0
- data/spec/motion/core/string_spec.rb +11 -5
- data/spec/motion/core_spec.rb +13 -2
- data/spec/motion/http/query_spec.rb +731 -0
- data/spec/motion/http/response_spec.rb +44 -0
- data/spec/motion/http_spec.rb +0 -722
- data/spec/motion/{core → ui}/gestures_spec.rb +0 -0
- data/spec/motion/ui/ui_alert_view_spec.rb +1188 -0
- data/spec/motion/{core → ui}/ui_bar_button_item_spec.rb +80 -24
- data/spec/motion/{core → ui}/ui_control_spec.rb +0 -0
- data/spec/motion/util/constants_spec.rb +4 -4
- metadata +86 -26
@@ -0,0 +1,59 @@
|
|
1
|
+
module BubbleWrap
|
2
|
+
module Device
|
3
|
+
module_function
|
4
|
+
|
5
|
+
# Verifies that the device running the app is an iPhone.
|
6
|
+
# @return [TrueClass, FalseClass] true will be returned if the device is an iPhone, false otherwise.
|
7
|
+
def iphone?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
|
8
|
+
idiom == UIUserInterfaceIdiomPhone
|
9
|
+
end
|
10
|
+
|
11
|
+
# Verifies that the device running the app is an iPad.
|
12
|
+
# @return [TrueClass, FalseClass] true will be returned if the device is an iPad, false otherwise.
|
13
|
+
def ipad?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
|
14
|
+
idiom == UIUserInterfaceIdiomPad
|
15
|
+
end
|
16
|
+
|
17
|
+
# Verifies that the device having a long screen (4 inch iPhone/iPod)
|
18
|
+
# @return [TrueClass, FalseClass] true will be returned if the device is an iPhone/iPod with 4 inche screen, false otherwise.
|
19
|
+
def long_screen?(idiom=UIDevice.currentDevice.userInterfaceIdiom, screen_height=UIScreen.mainScreen.bounds.size.height)
|
20
|
+
iphone?(idiom) && screen_height == 568.0
|
21
|
+
end
|
22
|
+
|
23
|
+
# Use this to make a DSL-style call for picking images
|
24
|
+
# @example Device.camera.front
|
25
|
+
# @return [Device::Camera::CameraWrapper]
|
26
|
+
def camera
|
27
|
+
BubbleWrap::Device::CameraWrapper
|
28
|
+
end
|
29
|
+
|
30
|
+
# Verifies that the device running has a front facing camera.
|
31
|
+
# @return [TrueClass, FalseClass] true will be returned if the device has a front facing camera, false otherwise.
|
32
|
+
def front_camera?(picker=UIImagePickerController)
|
33
|
+
p "This method (front_camera?) is DEPRECATED. Transition to using Device.camera.front?"
|
34
|
+
picker.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceFront)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Verifies that the device running has a rear facing camera.
|
38
|
+
# @return [TrueClass, FalseClass] true will be returned if the device has a rear facing camera, false otherwise.
|
39
|
+
def rear_camera?(picker=UIImagePickerController)
|
40
|
+
p "This method (rear_camera?) is DEPRECATED. Transition to using Device.camera.rear?"
|
41
|
+
picker.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear)
|
42
|
+
end
|
43
|
+
|
44
|
+
def simulator?
|
45
|
+
@simulator_state ||= !(UIDevice.currentDevice.model =~ /simulator/i).nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the IOS SDK version currently running (i.e. "5.1" or "6.0" etc)
|
49
|
+
# @return [String] the IOS SDK version currently running
|
50
|
+
def ios_version
|
51
|
+
UIDevice.currentDevice.systemVersion
|
52
|
+
end
|
53
|
+
|
54
|
+
# Delegates to BubbleWrap::Screen.orientation
|
55
|
+
def orientation
|
56
|
+
screen.orientation
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/motion/core/string.rb
CHANGED
@@ -48,7 +48,8 @@ module BubbleWrap
|
|
48
48
|
def to_color
|
49
49
|
# First check if it is a color keyword
|
50
50
|
keyword_selector = "#{self.camelize(:lower)}Color"
|
51
|
-
|
51
|
+
color_klass = App.osx? ? NSColor : UIColor
|
52
|
+
return color_klass.send(keyword_selector) if color_klass.respond_to? keyword_selector
|
52
53
|
|
53
54
|
# Next attempt to convert from hex
|
54
55
|
hex_color = self.gsub("#", "")
|
@@ -61,7 +62,7 @@ module BubbleWrap
|
|
61
62
|
raise ArgumentError
|
62
63
|
end
|
63
64
|
if colors.size == 3
|
64
|
-
|
65
|
+
BubbleWrap.rgb_color(colors[0], colors[1], colors[2])
|
65
66
|
else
|
66
67
|
raise ArgumentError
|
67
68
|
end
|
data/motion/http.rb
CHANGED
@@ -27,370 +27,6 @@ module BubbleWrap
|
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
30
|
-
|
31
|
-
# Response class wrapping the results of a Query's response
|
32
|
-
class Response
|
33
|
-
attr_reader :body
|
34
|
-
attr_reader :headers
|
35
|
-
attr_accessor :status_code, :status_description, :error_message
|
36
|
-
attr_reader :url
|
37
|
-
attr_reader :original_url
|
38
|
-
|
39
|
-
def initialize(values={})
|
40
|
-
self.update(values)
|
41
|
-
end
|
42
|
-
|
43
|
-
def update(values)
|
44
|
-
values.each do |k,v|
|
45
|
-
self.instance_variable_set("@#{k}", v)
|
46
|
-
end
|
47
|
-
update_status_description
|
48
|
-
end
|
49
|
-
|
50
|
-
def ok?
|
51
|
-
status_code.to_s =~ /20\d/ ? true : false
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_s
|
55
|
-
"#<#{self.class}:#{self.object_id} - url: #{self.url}, body: #{self.body}, headers: #{self.headers}, status code: #{self.status_code}, error message: #{self.error_message} >"
|
56
|
-
end
|
57
|
-
alias description to_s
|
58
|
-
|
59
|
-
def update_status_description
|
60
|
-
@status_description = status_code.nil? ? nil : NSHTTPURLResponse.localizedStringForStatusCode(status_code)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Class wrapping NSConnection and often used indirectly by the BubbleWrap::HTTP module methods.
|
65
|
-
class Query
|
66
|
-
attr_accessor :request
|
67
|
-
attr_accessor :connection
|
68
|
-
attr_accessor :credentials # username & password has a hash
|
69
|
-
attr_accessor :proxy_credential # credential supplied to proxy servers
|
70
|
-
attr_accessor :post_data
|
71
|
-
attr_reader :method
|
72
|
-
|
73
|
-
attr_reader :response
|
74
|
-
attr_reader :status_code
|
75
|
-
attr_reader :response_headers
|
76
|
-
attr_reader :response_size
|
77
|
-
attr_reader :options
|
78
|
-
CLRF = "\r\n"
|
79
|
-
# ==== Parameters
|
80
|
-
# url<String>:: url of the resource to download
|
81
|
-
# http_method<Symbol>:: Value representing the HTTP method to use
|
82
|
-
# options<Hash>:: optional options used for the query
|
83
|
-
#
|
84
|
-
# ==== Options
|
85
|
-
# :payload<String> - data to pass to a POST, PUT, DELETE query.
|
86
|
-
# :delegator - Proc, class or object to call when the file is downloaded.
|
87
|
-
# a proc will receive a Response object while the passed object
|
88
|
-
# will receive the handle_query_response method
|
89
|
-
# :headers<Hash> - headers send with the request
|
90
|
-
# :cookies<Boolean> - Set whether cookies should be sent with request or not (Default: true)
|
91
|
-
# Anything else will be available via the options attribute reader.
|
92
|
-
#
|
93
|
-
def initialize(url_string, http_method = :get, options={})
|
94
|
-
@method = http_method.upcase.to_s
|
95
|
-
@delegator = options.delete(:action) || self
|
96
|
-
@payload = options.delete(:payload)
|
97
|
-
@files = options.delete(:files)
|
98
|
-
@boundary = options.delete(:boundary) || BW.create_uuid
|
99
|
-
@credentials = options.delete(:credentials) || {}
|
100
|
-
@credentials = {:username => '', :password => ''}.merge(@credentials)
|
101
|
-
@timeout = options.delete(:timeout) || 30.0
|
102
|
-
@headers = escape_line_feeds(options.delete :headers)
|
103
|
-
@format = options.delete(:format)
|
104
|
-
@cache_policy = options.delete(:cache_policy) || NSURLRequestUseProtocolCachePolicy
|
105
|
-
@credential_persistence = options.delete(:credential_persistence) || NSURLCredentialPersistenceForSession
|
106
|
-
@cookies = options.key?(:cookies) ? options.delete(:cookies) : true
|
107
|
-
@options = options
|
108
|
-
@response = HTTP::Response.new
|
109
|
-
@follow_urls = options[:follow_urls] || true
|
110
|
-
|
111
|
-
@url = create_url(url_string)
|
112
|
-
@body = create_request_body
|
113
|
-
@request = create_request
|
114
|
-
@original_url = @url.copy
|
115
|
-
|
116
|
-
@connection = create_connection(request, self)
|
117
|
-
@connection.start
|
118
|
-
|
119
|
-
UIApplication.sharedApplication.networkActivityIndicatorVisible = true if defined?(UIApplication)
|
120
|
-
end
|
121
|
-
|
122
|
-
def to_s
|
123
|
-
"#<#{self.class}:#{self.object_id} - Method: #{@method}, url: #{@url.description}, body: #{@body.description}, Payload: #{@payload}, Headers: #{@headers} Credentials: #{@credentials}, Timeout: #{@timeout}, \
|
124
|
-
Cache policy: #{@cache_policy}, response: #{@response.inspect} >"
|
125
|
-
end
|
126
|
-
alias description to_s
|
127
|
-
|
128
|
-
def connection(connection, didReceiveResponse:response)
|
129
|
-
@status_code = response.statusCode
|
130
|
-
@response_headers = response.allHeaderFields
|
131
|
-
@response_size = response.expectedContentLength.to_f
|
132
|
-
end
|
133
|
-
|
134
|
-
# This delegate method get called every time a chunk of data is being received
|
135
|
-
def connection(connection, didReceiveData:received_data)
|
136
|
-
@received_data ||= NSMutableData.new
|
137
|
-
@received_data.appendData(received_data)
|
138
|
-
|
139
|
-
if download_progress = options[:download_progress]
|
140
|
-
download_progress.call(@received_data.length.to_f, response_size)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def connection(connection, willSendRequest:request, redirectResponse:redirect_response)
|
145
|
-
# abort early if the user has explicitly disabled redirects
|
146
|
-
if @options[:no_redirect] and redirect_response then
|
147
|
-
return nil
|
148
|
-
end
|
149
|
-
@redirect_count ||= 0
|
150
|
-
@redirect_count += 1
|
151
|
-
log "##{@redirect_count} HTTP redirect_count: #{request.inspect} - #{self.description}"
|
152
|
-
|
153
|
-
if @redirect_count >= 30
|
154
|
-
@response.error_message = "Too many redirections"
|
155
|
-
@request.done_loading!
|
156
|
-
call_delegator_with_response
|
157
|
-
nil
|
158
|
-
else
|
159
|
-
@url = request.URL if @follow_urls
|
160
|
-
request
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def connection(connection, didFailWithError: error)
|
165
|
-
log "HTTP Connection to #{@url.absoluteString} failed #{error.localizedDescription}"
|
166
|
-
UIApplication.sharedApplication.networkActivityIndicatorVisible = false if defined?(UIApplication)
|
167
|
-
@request.done_loading!
|
168
|
-
@response.error_message = error.localizedDescription
|
169
|
-
call_delegator_with_response
|
170
|
-
end
|
171
|
-
|
172
|
-
def connection(connection, didSendBodyData:sending, totalBytesWritten:written, totalBytesExpectedToWrite:expected)
|
173
|
-
if upload_progress = options[:upload_progress]
|
174
|
-
upload_progress.call(sending, written, expected)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def connectionDidFinishLoading(connection)
|
179
|
-
UIApplication.sharedApplication.networkActivityIndicatorVisible = false if defined?(UIApplication)
|
180
|
-
@request.done_loading!
|
181
|
-
response_body = NSData.dataWithData(@received_data) if @received_data
|
182
|
-
@response.update(status_code: status_code, body: response_body, headers: response_headers, url: @url, original_url: @original_url)
|
183
|
-
|
184
|
-
call_delegator_with_response
|
185
|
-
end
|
186
|
-
|
187
|
-
def connection(connection, didReceiveAuthenticationChallenge:challenge)
|
188
|
-
if (challenge.previousFailureCount == 0)
|
189
|
-
if credentials[:username].to_s.empty? && credentials[:password].to_s.empty?
|
190
|
-
challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge)
|
191
|
-
log 'Continue without credentials to get 401 status in response'
|
192
|
-
else
|
193
|
-
new_credential = NSURLCredential.credentialWithUser(credentials[:username], password:credentials[:password], persistence:@credential_persistence)
|
194
|
-
challenge.sender.useCredential(new_credential, forAuthenticationChallenge:challenge)
|
195
|
-
log "auth challenged, answered with credentials: #{credentials.inspect}"
|
196
|
-
end
|
197
|
-
else
|
198
|
-
challenge.sender.cancelAuthenticationChallenge(challenge)
|
199
|
-
log 'Auth Failed :('
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
|
204
|
-
private
|
205
|
-
|
206
|
-
def create_request
|
207
|
-
log "BubbleWrap::HTTP building a NSRequest for #{@url.description}"
|
208
|
-
|
209
|
-
request = NSMutableURLRequest.requestWithURL(@url,
|
210
|
-
cachePolicy:@cache_policy,
|
211
|
-
timeoutInterval:@timeout)
|
212
|
-
request.setHTTPMethod(@method)
|
213
|
-
set_content_type
|
214
|
-
request.setAllHTTPHeaderFields(@headers)
|
215
|
-
request.setHTTPBody(@body)
|
216
|
-
request.setHTTPShouldHandleCookies(@cookies)
|
217
|
-
patch_nsurl_request(request)
|
218
|
-
|
219
|
-
request
|
220
|
-
end
|
221
|
-
|
222
|
-
def set_content_type
|
223
|
-
return if headers_provided?
|
224
|
-
return if (@method == "GET" || @method == "HEAD")
|
225
|
-
@headers ||= {}
|
226
|
-
@headers["Content-Type"] = case @format
|
227
|
-
when :json
|
228
|
-
"application/json"
|
229
|
-
when :xml
|
230
|
-
"application/xml"
|
231
|
-
when :text
|
232
|
-
"text/plain"
|
233
|
-
else
|
234
|
-
if @format == :form_data || @payload_or_files_were_appended
|
235
|
-
"multipart/form-data; boundary=#{@boundary}"
|
236
|
-
else
|
237
|
-
"application/x-www-form-urlencoded"
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
def headers_provided?
|
243
|
-
@headers && @headers.keys.find {|k| k.downcase == 'content-type'}
|
244
|
-
end
|
245
|
-
|
246
|
-
def create_request_body
|
247
|
-
return nil if (@method == "GET" || @method == "HEAD")
|
248
|
-
return nil unless (@payload || @files)
|
249
|
-
|
250
|
-
body = NSMutableData.data
|
251
|
-
|
252
|
-
append_payload(body) if @payload
|
253
|
-
append_files(body) if @files
|
254
|
-
append_body_boundary(body) if @payload_or_files_were_appended
|
255
|
-
|
256
|
-
log "Built HTTP body: \n #{body.to_str}"
|
257
|
-
body
|
258
|
-
end
|
259
|
-
|
260
|
-
def append_payload(body)
|
261
|
-
if @payload.is_a?(NSData)
|
262
|
-
body.appendData(@payload)
|
263
|
-
elsif @payload.is_a?(String)
|
264
|
-
body.appendData(@payload.dataUsingEncoding NSUTF8StringEncoding)
|
265
|
-
else
|
266
|
-
append_form_params(body)
|
267
|
-
end
|
268
|
-
body
|
269
|
-
end
|
270
|
-
|
271
|
-
def append_form_params(body)
|
272
|
-
list = process_payload_hash(@payload)
|
273
|
-
list.each do |key, value|
|
274
|
-
s = "--#{@boundary}\r\n"
|
275
|
-
s += "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n"
|
276
|
-
s += value.to_s
|
277
|
-
s += "\r\n"
|
278
|
-
body.appendData(s.dataUsingEncoding NSUTF8StringEncoding)
|
279
|
-
end
|
280
|
-
@payload_or_files_were_appended = true
|
281
|
-
body
|
282
|
-
end
|
283
|
-
|
284
|
-
def parse_file(key, value)
|
285
|
-
if value.is_a?(Hash)
|
286
|
-
raise InvalidFileError if value[:data].nil?
|
287
|
-
{data: value[:data], filename: value[:filename] || key}
|
288
|
-
else
|
289
|
-
{data: value, filename: key}
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
def append_files(body)
|
294
|
-
@files.each do |key, value|
|
295
|
-
file = parse_file(key, value)
|
296
|
-
s = "--#{@boundary}\r\n"
|
297
|
-
s += "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{file[:filename]}\"\r\n"
|
298
|
-
s += "Content-Type: application/octet-stream\r\n\r\n"
|
299
|
-
file_data = NSMutableData.new
|
300
|
-
file_data.appendData(s.dataUsingEncoding NSUTF8StringEncoding)
|
301
|
-
file_data.appendData(file[:data])
|
302
|
-
file_data.appendData("\r\n".dataUsingEncoding NSUTF8StringEncoding)
|
303
|
-
body.appendData(file_data)
|
304
|
-
end
|
305
|
-
@payload_or_files_were_appended = true
|
306
|
-
body
|
307
|
-
end
|
308
|
-
|
309
|
-
def append_body_boundary(body)
|
310
|
-
body.appendData("--#{@boundary}--\r\n".dataUsingEncoding NSUTF8StringEncoding)
|
311
|
-
end
|
312
|
-
|
313
|
-
def create_url(url_string)
|
314
|
-
url_string = url_string.stringByAddingPercentEscapesUsingEncoding NSUTF8StringEncoding
|
315
|
-
if (@method == "GET" || @method == "HEAD") && @payload
|
316
|
-
convert_payload_to_url if @payload.is_a?(Hash)
|
317
|
-
url_string += "?#{@payload}"
|
318
|
-
end
|
319
|
-
url = NSURL.URLWithString(url_string)
|
320
|
-
|
321
|
-
validate_url(url)
|
322
|
-
url
|
323
|
-
end
|
324
|
-
|
325
|
-
def validate_url(url)
|
326
|
-
if !NSURLConnection.canHandleRequest(NSURLRequest.requestWithURL(url))
|
327
|
-
raise InvalidURLError, "Invalid URL provided (Make sure you include a valid URL scheme, e.g. http:// or similar)."
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
|
-
def escape(string)
|
332
|
-
if string
|
333
|
-
CFURLCreateStringByAddingPercentEscapes nil, string.to_s, nil, "!*'();:@&=+$,/?%#[]", KCFStringEncodingUTF8
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
|
-
def convert_payload_to_url
|
338
|
-
params_array = process_payload_hash(@payload)
|
339
|
-
params_array.map! { |key, value| "#{escape key}=#{escape value}" }
|
340
|
-
@payload = params_array.join("&")
|
341
|
-
end
|
342
|
-
|
343
|
-
def process_payload_hash(payload, prefix=nil)
|
344
|
-
list = []
|
345
|
-
payload.each do |k,v|
|
346
|
-
if v.is_a?(Hash)
|
347
|
-
new_prefix = prefix ? "#{prefix}[#{k.to_s}]" : k.to_s
|
348
|
-
param = process_payload_hash(v, new_prefix)
|
349
|
-
list += param
|
350
|
-
elsif v.is_a?(Array)
|
351
|
-
v.each do |val|
|
352
|
-
param = prefix ? "#{prefix}[#{k.to_s}][]" : "#{k.to_s}[]"
|
353
|
-
list << [param, val]
|
354
|
-
end
|
355
|
-
else
|
356
|
-
param = prefix ? "#{prefix}[#{k.to_s}]" : k.to_s
|
357
|
-
list << [param, v]
|
358
|
-
end
|
359
|
-
end
|
360
|
-
list
|
361
|
-
end
|
362
|
-
|
363
|
-
def log(message)
|
364
|
-
NSLog message if BubbleWrap.debug?
|
365
|
-
end
|
366
|
-
|
367
|
-
def escape_line_feeds(hash)
|
368
|
-
return nil if hash.nil?
|
369
|
-
escaped_hash = {}
|
370
|
-
|
371
|
-
hash.each{|k,v| escaped_hash[k] = v.gsub("\n", CLRF) if v }
|
372
|
-
escaped_hash
|
373
|
-
end
|
374
|
-
|
375
|
-
def patch_nsurl_request(request)
|
376
|
-
request.instance_variable_set("@done_loading", false)
|
377
|
-
|
378
|
-
def request.done_loading?; @done_loading; end
|
379
|
-
def request.done_loading!; @done_loading = true; end
|
380
|
-
end
|
381
|
-
|
382
|
-
def call_delegator_with_response
|
383
|
-
if @delegator.respond_to?(:call)
|
384
|
-
@delegator.call( @response, self )
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
# This is a temporary method used for mocking.
|
389
|
-
def create_connection(request, delegate)
|
390
|
-
NSURLConnection.connectionWithRequest(request, delegate:delegate)
|
391
|
-
end
|
392
|
-
|
393
|
-
end
|
394
30
|
end
|
395
31
|
end
|
396
32
|
|