bubble-wrap 1.5.0 → 1.6.0.rc1

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.
@@ -0,0 +1,58 @@
1
+ describe BubbleWrap::UIActivityViewController do
2
+ before do
3
+ @controller = UIViewController.alloc.init
4
+ @controller.instance_eval do
5
+ def presentViewController(*args)
6
+ true
7
+ end
8
+ end
9
+
10
+ @options = options = {
11
+ item:"BubbleWrap!!!",
12
+ animated:false
13
+ }
14
+ end
15
+
16
+ after do
17
+ presenting_controller ||= App.window.rootViewController.presentedViewController
18
+ presenting_controller ||= App.window.rootViewController
19
+ presenting_controller.dismissViewControllerAnimated(false, completion:nil)
20
+ end
21
+
22
+ it 'Creates an instance of UIActivityViewController' do
23
+ activity = BW::UIActivityViewController.new(@options)
24
+
25
+ activity.kind_of?(UIActivityViewController).should == true
26
+ activity.excludedActivityTypes.should == nil
27
+ activity.activityItems.is_a?(Array).should == true
28
+ activity.activityItems.count.should == 1
29
+ end
30
+
31
+ it 'Sets a completion block' do
32
+ activity = BW::UIActivityViewController.new(@options) do |activity_type, completed|
33
+ test = 2
34
+ end
35
+ activity.completionHandler.should.not == nil
36
+ end
37
+
38
+ it 'Sets multiple items' do
39
+ options = @options.tap { |o| o.delete(:item) }.merge(items: ["Hello", "BubbleWrap!"])
40
+
41
+ activity = BW::UIActivityViewController.new(options)
42
+ activity.activityItems.is_a?(Array).should == true
43
+ activity.activityItems.count.should == 2
44
+ end
45
+
46
+ it 'Sets a single excluded activity' do
47
+ activity = BW::UIActivityViewController.new(@options.merge(excluded: :print))
48
+ activity.excludedActivityTypes.is_a?(Array).should == true
49
+ activity.excludedActivityTypes.count.should == 1
50
+ end
51
+
52
+ it 'Sets multiple excluded activities' do
53
+ activity = BW::UIActivityViewController.new(@options.merge(excluded: [:print, :add_to_reading_list]))
54
+ activity.excludedActivityTypes.is_a?(Array).should == true
55
+ activity.excludedActivityTypes.count.should == 2
56
+ end
57
+
58
+ end
@@ -22,5 +22,11 @@ describe BubbleWrap::Constants do
22
22
  it "should bitmask array values" do
23
23
  BW::Constants.get("NSStringEncodingConversion", :allow_lossy, :external_representation).should == (NSStringEncodingConversionAllowLossy | NSStringEncodingConversionExternalRepresentation)
24
24
  end
25
+
26
+ if App.ios?
27
+ it "should return an array of string constant values" do
28
+ BW::Constants.get("UIActivityType", [:air_drop, :print]).should == ["com.apple.UIKit.activity.AirDrop", "com.apple.UIKit.activity.Print"]
29
+ end
30
+ end
25
31
  end
26
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bubble-wrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Aimonetti
@@ -14,8 +14,22 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2014-03-04 00:00:00.000000000 Z
17
+ date: 2014-04-16 00:00:00.000000000 Z
18
18
  dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: bubble-wrap-http
21
+ requirement: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - '='
24
+ - !ruby/object:Gem::Version
25
+ version: 1.6.0.rc1
26
+ type: :runtime
27
+ prerelease: false
28
+ version_requirements: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - '='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.6.0.rc1
19
33
  - !ruby/object:Gem::Dependency
20
34
  name: mocha
21
35
  requirement: !ruby/object:Gem::Requirement
@@ -109,15 +123,13 @@ extra_rdoc_files:
109
123
  - motion/core/string.rb
110
124
  - motion/core/time.rb
111
125
  - motion/font/font.rb
112
- - motion/http.rb
113
- - motion/http/query.rb
114
- - motion/http/response.rb
115
126
  - motion/location/location.rb
116
127
  - motion/location/pollute.rb
117
128
  - motion/mail/mail.rb
118
129
  - motion/mail/result.rb
119
130
  - motion/media/media.rb
120
131
  - motion/media/player.rb
132
+ - motion/network-indicator/network-indicator.rb
121
133
  - motion/reactor.rb
122
134
  - motion/reactor/default_deferrable.rb
123
135
  - motion/reactor/deferrable.rb
@@ -132,6 +144,7 @@ extra_rdoc_files:
132
144
  - motion/sms/sms.rb
133
145
  - motion/test_suite_delegate.rb
134
146
  - motion/ui/pollute.rb
147
+ - motion/ui/ui_activity_view_controller_wrapper.rb
135
148
  - motion/ui/ui_alert_view.rb
136
149
  - motion/ui/ui_bar_button_item.rb
137
150
  - motion/ui/ui_control_wrapper.rb
@@ -160,19 +173,18 @@ extra_rdoc_files:
160
173
  - spec/motion/core/time_spec.rb
161
174
  - spec/motion/core_spec.rb
162
175
  - spec/motion/font/font_spec.rb
163
- - spec/motion/http/query_spec.rb
164
- - spec/motion/http/response_spec.rb
165
- - spec/motion/http_spec.rb
166
176
  - spec/motion/location/location_spec.rb
167
177
  - spec/motion/mail/mail_spec.rb
168
178
  - spec/motion/mail/result_spec.rb
169
179
  - spec/motion/media/player_spec.rb
180
+ - spec/motion/network-indicator/network_indicator_spec.rb
170
181
  - spec/motion/reactor/eventable_spec.rb
171
182
  - spec/motion/reactor_spec.rb
172
183
  - spec/motion/rss_parser_spec.rb
173
184
  - spec/motion/sms/result_spec.rb
174
185
  - spec/motion/sms/sms_spec.rb
175
186
  - spec/motion/ui/pollute_spec.rb
187
+ - spec/motion/ui/ui_activity_view_controller_wrapper_spec.rb
176
188
  - spec/motion/ui/ui_alert_view_spec.rb
177
189
  - spec/motion/ui/ui_bar_button_item_spec.rb
178
190
  - spec/motion/ui/ui_control_wrapper_spec.rb
@@ -206,6 +218,7 @@ files:
206
218
  - lib/bubble-wrap/location.rb
207
219
  - lib/bubble-wrap/mail.rb
208
220
  - lib/bubble-wrap/media.rb
221
+ - lib/bubble-wrap/network-indicator.rb
209
222
  - lib/bubble-wrap/reactor.rb
210
223
  - lib/bubble-wrap/requirement.rb
211
224
  - lib/bubble-wrap/requirement/path_manipulation.rb
@@ -237,15 +250,13 @@ files:
237
250
  - motion/core/string.rb
238
251
  - motion/core/time.rb
239
252
  - motion/font/font.rb
240
- - motion/http.rb
241
- - motion/http/query.rb
242
- - motion/http/response.rb
243
253
  - motion/location/location.rb
244
254
  - motion/location/pollute.rb
245
255
  - motion/mail/mail.rb
246
256
  - motion/mail/result.rb
247
257
  - motion/media/media.rb
248
258
  - motion/media/player.rb
259
+ - motion/network-indicator/network-indicator.rb
249
260
  - motion/reactor.rb
250
261
  - motion/reactor/default_deferrable.rb
251
262
  - motion/reactor/deferrable.rb
@@ -260,6 +271,7 @@ files:
260
271
  - motion/sms/sms.rb
261
272
  - motion/test_suite_delegate.rb
262
273
  - motion/ui/pollute.rb
274
+ - motion/ui/ui_activity_view_controller_wrapper.rb
263
275
  - motion/ui/ui_alert_view.rb
264
276
  - motion/ui/ui_bar_button_item.rb
265
277
  - motion/ui/ui_control_wrapper.rb
@@ -340,19 +352,18 @@ files:
340
352
  - spec/motion/core/time_spec.rb
341
353
  - spec/motion/core_spec.rb
342
354
  - spec/motion/font/font_spec.rb
343
- - spec/motion/http/query_spec.rb
344
- - spec/motion/http/response_spec.rb
345
- - spec/motion/http_spec.rb
346
355
  - spec/motion/location/location_spec.rb
347
356
  - spec/motion/mail/mail_spec.rb
348
357
  - spec/motion/mail/result_spec.rb
349
358
  - spec/motion/media/player_spec.rb
359
+ - spec/motion/network-indicator/network_indicator_spec.rb
350
360
  - spec/motion/reactor/eventable_spec.rb
351
361
  - spec/motion/reactor_spec.rb
352
362
  - spec/motion/rss_parser_spec.rb
353
363
  - spec/motion/sms/result_spec.rb
354
364
  - spec/motion/sms/sms_spec.rb
355
365
  - spec/motion/ui/pollute_spec.rb
366
+ - spec/motion/ui/ui_activity_view_controller_wrapper_spec.rb
356
367
  - spec/motion/ui/ui_alert_view_spec.rb
357
368
  - spec/motion/ui/ui_bar_button_item_spec.rb
358
369
  - spec/motion/ui/ui_control_wrapper_spec.rb
@@ -360,7 +371,6 @@ files:
360
371
  - spec/motion/ui/ui_view_wrapper_spec.rb
361
372
  - spec/motion/util/constants_spec.rb
362
373
  - spec/motion/util/deprecated_spec.rb
363
- - travis.sh
364
374
  homepage: http://bubblewrap.io/
365
375
  licenses: []
366
376
  metadata: {}
@@ -375,9 +385,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
375
385
  version: '0'
376
386
  required_rubygems_version: !ruby/object:Gem::Requirement
377
387
  requirements:
378
- - - '>='
388
+ - - '>'
379
389
  - !ruby/object:Gem::Version
380
- version: '0'
390
+ version: 1.3.1
381
391
  requirements: []
382
392
  rubyforge_project:
383
393
  rubygems_version: 2.0.3
@@ -410,19 +420,18 @@ test_files:
410
420
  - spec/motion/core/time_spec.rb
411
421
  - spec/motion/core_spec.rb
412
422
  - spec/motion/font/font_spec.rb
413
- - spec/motion/http/query_spec.rb
414
- - spec/motion/http/response_spec.rb
415
- - spec/motion/http_spec.rb
416
423
  - spec/motion/location/location_spec.rb
417
424
  - spec/motion/mail/mail_spec.rb
418
425
  - spec/motion/mail/result_spec.rb
419
426
  - spec/motion/media/player_spec.rb
427
+ - spec/motion/network-indicator/network_indicator_spec.rb
420
428
  - spec/motion/reactor/eventable_spec.rb
421
429
  - spec/motion/reactor_spec.rb
422
430
  - spec/motion/rss_parser_spec.rb
423
431
  - spec/motion/sms/result_spec.rb
424
432
  - spec/motion/sms/sms_spec.rb
425
433
  - spec/motion/ui/pollute_spec.rb
434
+ - spec/motion/ui/ui_activity_view_controller_wrapper_spec.rb
426
435
  - spec/motion/ui/ui_alert_view_spec.rb
427
436
  - spec/motion/ui/ui_bar_button_item_spec.rb
428
437
  - spec/motion/ui/ui_control_wrapper_spec.rb
@@ -1,34 +0,0 @@
1
- module BubbleWrap
2
-
3
- # The HTTP module provides a simple interface to make HTTP requests.
4
- #
5
- # TODO: preflight support, easier/better cookie support, better error handling
6
- module HTTP
7
-
8
- # Make a GET request and process the response asynchronously via a block.
9
- #
10
- # @examples
11
- # # Simple GET request printing the body
12
- # BubbleWrap::HTTP.get("https://api.github.com/users/mattetti") do |response|
13
- # p response.body.to_str
14
- # end
15
- #
16
- # # GET request with basic auth credentials
17
- # BubbleWrap::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
18
- # p response.body.to_str # prints the response's body
19
- # end
20
- #
21
-
22
- [:get, :post, :put, :delete, :head, :options, :patch].each do |http_verb|
23
-
24
- define_singleton_method(http_verb) do |url, options = {}, &block|
25
- options[:action] = block if block
26
- HTTP::Query.new(url, http_verb, options)
27
- end
28
-
29
- end
30
- end
31
- end
32
-
33
- class InvalidURLError < StandardError; end
34
- class InvalidFileError < StandardError; end
@@ -1,393 +0,0 @@
1
- # Class wrapping NSConnection and often used indirectly by the BubbleWrap::HTTP module methods.
2
- module BubbleWrap; module HTTP; class Query
3
- attr_accessor :request
4
- attr_accessor :connection
5
- attr_accessor :credentials # username & password has a hash
6
- attr_accessor :proxy_credential # credential supplied to proxy servers
7
- attr_accessor :post_data
8
- attr_reader :method
9
-
10
- attr_reader :response
11
- attr_reader :status_code
12
- attr_reader :response_headers
13
- attr_reader :response_size
14
- attr_reader :options
15
- CLRF = "\r\n"
16
- # ==== Parameters
17
- # url<String>:: url of the resource to download
18
- # http_method<Symbol>:: Value representing the HTTP method to use
19
- # options<Hash>:: optional options used for the query
20
- #
21
- # ==== Options
22
- # :payload<String> - data to pass to a POST, PUT, DELETE query.
23
- # :action - Proc, class or object to call when the file is downloaded.
24
- # a proc will receive a Response object while the passed object
25
- # will receive the handle_query_response method
26
- # :headers<Hash> - headers send with the request
27
- # :cookies<Boolean> - Set whether cookies should be sent with request or not (Default: true)
28
- # Anything else will be available via the options attribute reader.
29
- #
30
- def initialize(url_string, http_method = :get, options={})
31
- @method = http_method.upcase.to_s
32
- @delegator = options.delete(:action) || self
33
- if @delegator.respond_to?("weak!")
34
- @delegator.weak! if BubbleWrap.use_weak_callbacks?
35
- end
36
-
37
- @payload = options.delete(:payload)
38
- @encoding = options.delete(:encoding) || NSUTF8StringEncoding
39
- @files = options.delete(:files)
40
- @boundary = options.delete(:boundary) || BW.create_uuid
41
- @credentials = options.delete(:credentials) || {}
42
- @credentials = {:username => nil, :password => nil}.merge(@credentials)
43
- @timeout = options.delete(:timeout) || 30.0
44
- @headers = escape_line_feeds(options.delete :headers)
45
- @format = options.delete(:format)
46
- @cache_policy = options.delete(:cache_policy) || NSURLRequestUseProtocolCachePolicy
47
- @credential_persistence = options.delete(:credential_persistence) || NSURLCredentialPersistenceForSession
48
- @cookies = options.key?(:cookies) ? options.delete(:cookies) : true
49
- @options = options
50
- @response = BubbleWrap::HTTP::Response.new
51
- @follow_urls = options[:follow_urls] || true
52
- @present_credentials = options[:present_credentials] == nil ? true : options.delete(:present_credentials)
53
-
54
- @url = create_url(url_string)
55
- @body = create_request_body
56
- @request = create_request
57
- @original_url = @url.copy
58
-
59
- @connection = create_connection(request, self)
60
- @connection.scheduleInRunLoop(NSRunLoop.currentRunLoop, forMode:NSRunLoopCommonModes)
61
- @connection.start
62
-
63
- show_status_indicator true
64
- end
65
-
66
- def to_s
67
- "#<#{self.class}:#{self.object_id} - Method: #{@method}, url: #{@url.description}, body: #{@body.description}, Payload: #{@payload}, Headers: #{@headers} Credentials: #{@credentials}, Timeout: #{@timeout}, \
68
- Cache policy: #{@cache_policy}, response: #{@response.inspect} >"
69
- end
70
- alias description to_s
71
-
72
- def connection(connection, didReceiveResponse:response)
73
- # On OSX, if using an FTP connection, this method will fire *immediately* after creating an
74
- # NSURLConnection, even if the connection has not yet started. The `response`
75
- # object will be a NSURLResponse, *not* an `NSHTTPURLResponse`, and so will start to crash.
76
- if App.osx? && !response.is_a?(NSHTTPURLResponse)
77
- return
78
- end
79
- did_receive_response(response)
80
- end
81
-
82
- # This delegate method get called every time a chunk of data is being received
83
- def connection(connection, didReceiveData:received_data)
84
- @received_data ||= NSMutableData.new
85
- @received_data.appendData(received_data)
86
-
87
- if download_progress = options[:download_progress]
88
- download_progress.call(@received_data.length.to_f, response_size)
89
- end
90
- end
91
-
92
- def connection(connection, willSendRequest:request, redirectResponse:redirect_response)
93
- # abort early if the user has explicitly disabled redirects
94
- if @options[:no_redirect] and redirect_response then
95
- return nil
96
- end
97
- @redirect_count ||= 0
98
- @redirect_count += 1
99
- log "##{@redirect_count} HTTP redirect_count: #{request.inspect} - #{self.description}"
100
-
101
- if @redirect_count >= 30
102
- @response.error = NSError.errorWithDomain('BubbleWrap::HTTP', code:NSURLErrorHTTPTooManyRedirects,
103
- userInfo:NSDictionary.dictionaryWithObject("Too many redirections",
104
- forKey: NSLocalizedDescriptionKey))
105
- @response.error_message = @response.error.localizedDescription
106
- show_status_indicator false
107
- @request.done_loading!
108
- call_delegator_with_response
109
- nil
110
- else
111
- @url = request.URL if @follow_urls
112
- request
113
- end
114
- end
115
-
116
- def connection(connection, didFailWithError: error)
117
- log "HTTP Connection to #{@url.absoluteString} failed #{error.localizedDescription}"
118
- show_status_indicator false
119
- @request.done_loading!
120
- @response.error = error
121
- @response.error_message = error.localizedDescription
122
- call_delegator_with_response
123
- end
124
-
125
- def connection(connection, didSendBodyData:sending, totalBytesWritten:written, totalBytesExpectedToWrite:expected)
126
- if upload_progress = options[:upload_progress]
127
- upload_progress.call(sending, written, expected)
128
- end
129
- end
130
-
131
- def connectionDidFinishLoading(connection)
132
- show_status_indicator false
133
- @request.done_loading!
134
- response_body = NSData.dataWithData(@received_data) if @received_data
135
- @response.update(status_code: status_code, body: response_body, headers: response_headers, url: @url, original_url: @original_url)
136
-
137
- call_delegator_with_response
138
- end
139
-
140
- def connection(connection, didReceiveAuthenticationChallenge:challenge)
141
- if (challenge.previousFailureCount == 0)
142
- if credentials[:username].to_s.empty? && credentials[:password].to_s.empty?
143
- challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge)
144
- log 'Continue without credentials to get 401 status in response'
145
- else
146
- new_credential = NSURLCredential.credentialWithUser(credentials[:username], password:credentials[:password], persistence:@credential_persistence)
147
- challenge.sender.useCredential(new_credential, forAuthenticationChallenge:challenge)
148
- log "auth challenged, answered with credentials: #{credentials.inspect}"
149
- end
150
- else
151
- did_receive_response(challenge.failureResponse)
152
- @response.update(status_code: status_code, headers: response_headers, url: @url, original_url: @original_url)
153
- challenge.sender.cancelAuthenticationChallenge(challenge)
154
- log 'Auth Failed :('
155
- end
156
- end
157
-
158
- def cancel
159
- @connection.cancel
160
- show_status_indicator false
161
- @request.done_loading!
162
- end
163
-
164
- private
165
-
166
- def did_receive_response(response)
167
- @status_code = response.statusCode
168
- @response_headers = response.allHeaderFields
169
- @response_size = response.expectedContentLength.to_f
170
- end
171
-
172
- def show_status_indicator(show)
173
- if App.ios?
174
- UIApplication.sharedApplication.networkActivityIndicatorVisible = show
175
- end
176
- end
177
-
178
- def create_request
179
- log "BubbleWrap::HTTP building a NSRequest for #{@url.description}"
180
-
181
- request = NSMutableURLRequest.requestWithURL(@url,
182
- cachePolicy:@cache_policy,
183
- timeoutInterval:@timeout)
184
- request.setHTTPMethod(@method)
185
- set_content_type
186
- append_auth_header
187
- request.setAllHTTPHeaderFields(@headers)
188
- request.setHTTPBody(@body)
189
- request.setHTTPShouldHandleCookies(@cookies)
190
- patch_nsurl_request(request)
191
-
192
- request
193
- end
194
-
195
- def set_content_type
196
- return if headers_provided?
197
- return if (@method == "GET" || @method == "HEAD" || @method == "OPTIONS")
198
- @headers ||= {}
199
- @headers["Content-Type"] = case @format
200
- when :json
201
- "application/json"
202
- when :xml
203
- "application/xml"
204
- when :text
205
- "text/plain"
206
- else
207
- if @format == :form_data || @payload_or_files_were_appended
208
- "multipart/form-data; boundary=#{@boundary}"
209
- else
210
- "application/x-www-form-urlencoded"
211
- end
212
- end
213
- end
214
-
215
- def headers_provided?
216
- @headers && @headers.keys.find {|k| k.downcase == 'content-type'}
217
- end
218
-
219
- def credentials_provided?
220
- @credentials[:username] && @credentials[:password]
221
- end
222
-
223
- def create_request_body
224
- return nil if (@method == "GET" || @method == "HEAD" || @method == "OPTIONS")
225
- return nil unless (@payload || @files)
226
-
227
- body = NSMutableData.data
228
-
229
- append_payload(body) if @payload
230
- append_files(body) if @files
231
- append_body_boundary(body) if @payload_or_files_were_appended
232
-
233
- log "Built HTTP body: \n #{body.to_str}"
234
- body
235
- end
236
-
237
- def append_payload(body)
238
- if @payload.is_a?(NSData)
239
- body.appendData(@payload)
240
- elsif @payload.is_a?(String)
241
- body.appendData(@payload.to_encoded_data @encoding)
242
- elsif @format == :json
243
- json_string = BW::JSON.generate(@payload)
244
- body.appendData(json_string.to_encoded_data @encoding)
245
- else
246
- append_form_params(body)
247
- end
248
- body
249
- end
250
-
251
- def append_form_params(body)
252
- list = process_payload_hash(@payload)
253
- list.each do |key, value|
254
- s = "--#{@boundary}\r\n"
255
- s += "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n"
256
- s += value.to_s
257
- s += "\r\n"
258
- body.appendData(s.to_encoded_data @encoding)
259
- end
260
- @payload_or_files_were_appended = true
261
- body
262
- end
263
-
264
- def append_auth_header
265
- return if @headers && @headers["Authorization"]
266
-
267
- if credentials_provided? && @present_credentials
268
- mock_request = CFHTTPMessageCreateRequest(nil, nil, nil, nil)
269
- CFHTTPMessageAddAuthentication(mock_request, nil, @credentials[:username], @credentials[:password], KCFHTTPAuthenticationSchemeBasic, false)
270
-
271
- @headers ||= {}
272
- @headers["Authorization"] = CFHTTPMessageCopyHeaderFieldValue(mock_request, "Authorization")
273
- end
274
- end
275
-
276
- def parse_file(key, value)
277
- value = {data: value} unless value.is_a?(Hash)
278
- raise(InvalidFileError, "You need to supply a `:data` entry in #{value} for file '#{key}' in your HTTP `:files`") if value[:data].nil?
279
- {
280
- data: value[:data],
281
- filename: value.fetch(:filename, key),
282
- content_type: value.fetch(:content_type, "application/octet-stream")
283
- }
284
- end
285
-
286
- def append_files(body)
287
- @files.each do |key, value|
288
- file = parse_file(key, value)
289
- s = "--#{@boundary}\r\n"
290
- s += "Content-Disposition: attachment; name=\"#{key}\"; filename=\"#{file[:filename]}\"\r\n"
291
- s += "Content-Type: #{file[:content_type]}\r\n\r\n"
292
- file_data = NSMutableData.new
293
- file_data.appendData(s.to_encoded_data @encoding)
294
- file_data.appendData(file[:data])
295
- file_data.appendData("\r\n".to_encoded_data @encoding)
296
- body.appendData(file_data)
297
- end
298
- @payload_or_files_were_appended = true
299
- body
300
- end
301
-
302
- def append_body_boundary(body)
303
- body.appendData("--#{@boundary}--\r\n".to_encoded_data @encoding)
304
- end
305
-
306
- def create_url(url_string)
307
- url_string = url_string.stringByAddingPercentEscapesUsingEncoding NSUTF8StringEncoding
308
- if (@method == "GET" || @method == "HEAD" || @method == "OPTIONS") && @payload
309
- unless @payload.empty?
310
- convert_payload_to_url if @payload.is_a?(Hash)
311
- url_string += "?#{@payload}"
312
- end
313
- end
314
- url = NSURL.URLWithString(url_string)
315
-
316
- validate_url(url)
317
- url
318
- end
319
-
320
- def validate_url(url)
321
- if !NSURLConnection.canHandleRequest(NSURLRequest.requestWithURL(url))
322
- raise InvalidURLError, "Invalid URL provided (Make sure you include a valid URL scheme, e.g. http:// or similar)."
323
- end
324
- end
325
-
326
- def escape(string)
327
- string_to_escape = string.to_s
328
- if string_to_escape
329
- CFURLCreateStringByAddingPercentEscapes nil, string_to_escape, nil, "!*'();:@&=+$,/?%#[]", KCFStringEncodingUTF8
330
- end
331
- end
332
-
333
- def convert_payload_to_url
334
- params_array = process_payload_hash(@payload)
335
- params_array.map! { |key, value| "#{escape key}=#{escape value}" }
336
- @payload = params_array.join("&")
337
- end
338
-
339
- def process_payload_hash(payload, prefix=nil)
340
- list = []
341
- payload.each do |k,v|
342
- if v.is_a?(Hash)
343
- new_prefix = prefix ? "#{prefix}[#{k.to_s}]" : k.to_s
344
- param = process_payload_hash(v, new_prefix)
345
- list += param
346
- elsif v.is_a?(Array)
347
- v.each do |val|
348
- param = prefix ? "#{prefix}[#{k.to_s}][]" : "#{k.to_s}[]"
349
- if val.is_a?(Hash)
350
- list += process_payload_hash(val, param)
351
- else
352
- list << [param, val]
353
- end
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.alloc.initWithRequest(request, delegate:delegate, startImmediately:false)
391
- end
392
-
393
- end; end; end