bubble-wrap 1.5.0 → 1.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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