bubble-wrap 1.4.0 → 1.5.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/Gemfile.lock +1 -1
- data/README.md +22 -2
- data/bubble-wrap.gemspec +7 -7
- data/lib/bubble-wrap.rb +1 -1
- data/lib/bubble-wrap/core.rb +3 -3
- data/lib/bubble-wrap/ext.rb +0 -1
- data/lib/bubble-wrap/ext/motion_project_app.rb +4 -3
- data/lib/bubble-wrap/loader.rb +3 -3
- data/lib/bubble-wrap/media.rb +2 -0
- data/lib/bubble-wrap/requirement.rb +1 -1
- data/lib/bubble-wrap/version.rb +2 -2
- data/motion/core/device/ios/camera.rb +33 -3
- data/motion/core/device/ios/camera_wrapper.rb +10 -0
- data/motion/core/kvo.rb +18 -2
- data/motion/core/ns_notification_center.rb +1 -0
- data/motion/core/time.rb +5 -0
- data/motion/http/query.rb +15 -9
- data/motion/location/location.rb +3 -2
- data/motion/mail/mail.rb +2 -1
- data/motion/media/player.rb +10 -2
- data/motion/reactor.rb +2 -0
- data/motion/reactor/periodic_timer.rb +2 -1
- data/motion/shortcut.rb +8 -0
- data/motion/sms/sms.rb +2 -0
- data/motion/ui/ui_alert_view.rb +2 -0
- data/motion/ui/ui_bar_button_item.rb +12 -2
- data/motion/ui/ui_control_wrapper.rb +1 -0
- data/motion/ui/ui_view_wrapper.rb +5 -0
- data/samples/osx/Gemfile.lock +7 -3
- data/spec/motion/core/device/ios/camera_spec.rb +6 -0
- data/spec/motion/core/device/ios/camera_wrapper_spec.rb +51 -2
- data/spec/motion/core/kvo_spec.rb +27 -0
- data/spec/motion/core/ns_notification_center_spec.rb +3 -3
- data/spec/motion/core/time_spec.rb +13 -4
- data/spec/motion/core_spec.rb +0 -1
- data/spec/motion/http/query_spec.rb +5 -5
- data/spec/motion/http_spec.rb +1 -1
- data/spec/motion/location/location_spec.rb +2 -2
- data/spec/motion/mail/mail_spec.rb +1 -1
- data/spec/motion/media/player_spec.rb +34 -12
- data/spec/motion/ui/ui_bar_button_item_spec.rb +76 -0
- data/spec/motion/ui/ui_control_wrapper_spec.rb +38 -0
- data/spec/motion/ui/ui_view_wrapper_spec.rb +42 -0
- metadata +4 -6
- data/lib/bubble-wrap/ext/motion_project_config.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fe8341489f7d867922c2a8c271efa986f434521
|
4
|
+
data.tar.gz: eb3ed530d9b58a39525049fe03286e83f4add2cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fadcc0db6e1ca10ba457ff651cac9b66315834dce161d33e026ebadafc78748da0fd481f59c78007754bd9c7f0cb45463b784160ec49bb354d202b7cab7f8d0a
|
7
|
+
data.tar.gz: 3ff86b7387349720e3aec8b48dba3efca6e7d1a2c988023634cfa693569a158124a1e1f41d50abe90068211b86971c0467c98cb207120077d10455d72dffa858
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -23,10 +23,10 @@ gem install bubble-wrap
|
|
23
23
|
require 'bubble-wrap'
|
24
24
|
```
|
25
25
|
|
26
|
-
If you
|
26
|
+
If you using Bundler:
|
27
27
|
|
28
28
|
```ruby
|
29
|
-
gem "bubble-wrap", "~> 1.
|
29
|
+
gem "bubble-wrap", "~> 1.4.0"
|
30
30
|
```
|
31
31
|
|
32
32
|
BubbleWrap is split into multiple modules so that you can easily choose which parts
|
@@ -479,6 +479,12 @@ button.when(UIControlEventTouchUpInside) do
|
|
479
479
|
end
|
480
480
|
```
|
481
481
|
|
482
|
+
Set the use_weak_callbacks flag so the blocks do not retain a strong reference to self:
|
483
|
+
|
484
|
+
```ruby
|
485
|
+
BubbleWrap.use_weak_callbacks = true
|
486
|
+
```
|
487
|
+
|
482
488
|
### UIBarButtonItem
|
483
489
|
|
484
490
|
`BW::UIBarButtonItem` is a subclass of `UIBarButtonItem` with an natural Ruby syntax.
|
@@ -626,6 +632,20 @@ BW::HTTP.post("http://foo.bar.com/", {payload: data}) do |response|
|
|
626
632
|
end
|
627
633
|
```
|
628
634
|
|
635
|
+
To upload files to a server, provide a `files:` hash:
|
636
|
+
|
637
|
+
```ruby
|
638
|
+
data = {token: "some-api-token"}
|
639
|
+
avatar_data = UIImagePNGRepresentation(UIImage.imageNamed("some-image"))
|
640
|
+
avatar = { data: avatar_data, filename: "some-image.png", content_type: "image/png" }
|
641
|
+
|
642
|
+
BW::HTTP.post("http://foo.bar.com/", {payload: data}, files: { avatar: avatar }) do |response|
|
643
|
+
if response.ok?
|
644
|
+
# files are uploaded
|
645
|
+
end
|
646
|
+
end
|
647
|
+
```
|
648
|
+
|
629
649
|
A `:download_progress` option can also be passed. The expected object
|
630
650
|
would be a Proc that takes two arguments: a float representing the
|
631
651
|
amount of data currently received and another float representing the
|
data/bubble-wrap.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
require File.expand_path('../lib/bubble-wrap/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = [
|
6
|
-
gem.email = [
|
7
|
-
gem.description =
|
8
|
-
gem.summary =
|
9
|
-
gem.homepage =
|
5
|
+
gem.authors = ['Matt Aimonetti', 'Francis Chong', 'James Harton', 'Clay Allsopp', 'Dylan Markow', 'Jan Weinkauff', 'Marin Usalj']
|
6
|
+
gem.email = ['mattaimonetti@gmail.com', 'francis@ignition.hk', 'james@sociable.co.nz', 'clay.allsopp@gmail.com', 'dylan@dylanmarkow.com', 'jan@dreimannzelt.de', 'mneorr@gmail.com']
|
7
|
+
gem.description = 'RubyMotion wrappers and helpers (Ruby for iOS) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull request.'
|
8
|
+
gem.summary = 'RubyMotion wrappers and helpers (Ruby for iOS) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull request.'
|
9
|
+
gem.homepage = 'http://bubblewrap.io/'
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
12
|
gem.test_files = gem.files.grep(%r{^(test|spec|lib_spec|features)/})
|
13
|
-
gem.name =
|
14
|
-
gem.require_paths = [
|
13
|
+
gem.name = 'bubble-wrap'
|
14
|
+
gem.require_paths = ['lib']
|
15
15
|
gem.version = BubbleWrap::VERSION
|
16
16
|
|
17
17
|
gem.extra_rdoc_files = gem.files.grep(%r{motion})
|
data/lib/bubble-wrap.rb
CHANGED
data/lib/bubble-wrap/core.rb
CHANGED
@@ -9,12 +9,12 @@ BubbleWrap.require('motion/core/device/*.rb')
|
|
9
9
|
BubbleWrap.require_ios do
|
10
10
|
BubbleWrap.require('motion/core/ios/**/*.rb')
|
11
11
|
BubbleWrap.require('motion/core/device/ios/**/*.rb')
|
12
|
+
|
13
|
+
require 'bubble-wrap/camera'
|
14
|
+
require 'bubble-wrap/ui'
|
12
15
|
end
|
13
16
|
|
14
17
|
BubbleWrap.require_osx do
|
15
18
|
BubbleWrap.require('motion/core/osx/**/*.rb')
|
16
19
|
BubbleWrap.require('motion/core/device/osx/**/*.rb')
|
17
20
|
end
|
18
|
-
|
19
|
-
require 'bubble-wrap/camera'
|
20
|
-
require 'bubble-wrap/ui'
|
data/lib/bubble-wrap/ext.rb
CHANGED
@@ -4,14 +4,15 @@ module BubbleWrap
|
|
4
4
|
|
5
5
|
def self.extended(base)
|
6
6
|
base.instance_eval do
|
7
|
-
def setup_with_bubblewrap(&block)
|
7
|
+
def setup_with_bubblewrap(*args, &block)
|
8
8
|
bw_config = proc do |app|
|
9
9
|
app.files = ::BubbleWrap::Requirement.files(app.files)
|
10
10
|
app.files_dependencies ::BubbleWrap::Requirement.files_dependencies
|
11
11
|
app.frameworks = ::BubbleWrap::Requirement.frameworks(app.frameworks)
|
12
12
|
block.call(app) unless block.nil?
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
|
+
setup_without_bubblewrap *args, &bw_config
|
15
16
|
end
|
16
17
|
alias :setup_without_bubblewrap :setup
|
17
18
|
alias :setup :setup_with_bubblewrap
|
@@ -30,4 +31,4 @@ end
|
|
30
31
|
|
31
32
|
Motion::Project::App.extend(BubbleWrap::Ext::BuildTask)
|
32
33
|
|
33
|
-
Motion::Project::App.extend(BubbleWrap::Ext::Platforms)
|
34
|
+
Motion::Project::App.extend(BubbleWrap::Ext::Platforms)
|
data/lib/bubble-wrap/loader.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
unless defined?(Motion::Project::Config)
|
2
|
-
raise
|
2
|
+
raise 'This file must be required within a RubyMotion project Rakefile.'
|
3
3
|
end
|
4
4
|
|
5
5
|
unless defined?(BubbleWrap::LOADER_PRESENT)
|
@@ -13,7 +13,7 @@ unless defined?(BubbleWrap::LOADER_PRESENT)
|
|
13
13
|
|
14
14
|
module BubbleWrap
|
15
15
|
|
16
|
-
LOADER_PRESENT=true
|
16
|
+
LOADER_PRESENT = true
|
17
17
|
module_function
|
18
18
|
|
19
19
|
def root
|
@@ -44,5 +44,5 @@ unless defined?(BubbleWrap::LOADER_PRESENT)
|
|
44
44
|
BW = BubbleWrap unless defined?(BW)
|
45
45
|
|
46
46
|
BW.require 'motion/shortcut.rb'
|
47
|
-
|
47
|
+
|
48
48
|
end
|
data/lib/bubble-wrap/media.rb
CHANGED
@@ -2,6 +2,8 @@ require 'bubble-wrap/loader'
|
|
2
2
|
|
3
3
|
BubbleWrap.require_ios("media") do
|
4
4
|
BubbleWrap.require('motion/core/app.rb')
|
5
|
+
BubbleWrap.require('motion/core/ios/app.rb')
|
6
|
+
BubbleWrap.require('motion/core/ios/device.rb')
|
5
7
|
BubbleWrap.require('motion/core/string.rb')
|
6
8
|
BubbleWrap.require('motion/core/ns_notification_center.rb')
|
7
9
|
BubbleWrap.require('motion/media/**/*.rb') do
|
@@ -85,7 +85,7 @@ module BubbleWrap
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def frameworks(app_frameworks=nil)
|
88
|
-
frameworks = ['
|
88
|
+
frameworks = ['Foundation', 'CoreGraphics'] +
|
89
89
|
paths.values.map(&:frameworks)
|
90
90
|
frameworks += app_frameworks if app_frameworks
|
91
91
|
frameworks.flatten.compact.sort.uniq
|
data/lib/bubble-wrap/version.rb
CHANGED
@@ -34,9 +34,21 @@ module BubbleWrap
|
|
34
34
|
@rear ||= Camera.new(:rear)
|
35
35
|
end
|
36
36
|
|
37
|
+
def self.available?
|
38
|
+
UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceTypeCamera)
|
39
|
+
end
|
40
|
+
|
37
41
|
# For uploading photos from the library.
|
38
|
-
|
39
|
-
|
42
|
+
class << self
|
43
|
+
def any
|
44
|
+
@any ||= Camera.new
|
45
|
+
end
|
46
|
+
alias_method "photo_library", "any"
|
47
|
+
end
|
48
|
+
|
49
|
+
def popover_from(view)
|
50
|
+
@popover_in_view = view
|
51
|
+
self
|
40
52
|
end
|
41
53
|
|
42
54
|
def initialize(location = :none)
|
@@ -78,6 +90,7 @@ module BubbleWrap
|
|
78
90
|
# end
|
79
91
|
def picture(options = {}, presenting_controller = nil, &block)
|
80
92
|
@callback = block
|
93
|
+
@callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
|
81
94
|
|
82
95
|
@options = options
|
83
96
|
@options[:allows_editing] = false if not @options.has_key? :allows_editing
|
@@ -124,7 +137,19 @@ module BubbleWrap
|
|
124
137
|
|
125
138
|
presenting_controller ||= App.window.rootViewController.presentedViewController # May be nil, but handles use case of container views
|
126
139
|
presenting_controller ||= App.window.rootViewController
|
127
|
-
|
140
|
+
|
141
|
+
# use popover for iPad (ignore on iPhone)
|
142
|
+
if Device.ipad? and source_type==UIImagePickerControllerSourceTypePhotoLibrary and @popover_in_view
|
143
|
+
@popover = UIPopoverController.alloc.initWithContentViewController(picker)
|
144
|
+
@popover.presentPopoverFromRect(@popover_in_view.bounds, inView:@popover_in_view, permittedArrowDirections:UIPopoverArrowDirectionAny, animated:@options[:animated])
|
145
|
+
else
|
146
|
+
presenting_controller.presentViewController(self.picker, animated:@options[:animated], completion: lambda {})
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# iPad popover is dismissed
|
151
|
+
def popoverControllerDidDismissPopover(popoverController)
|
152
|
+
@popover = nil
|
128
153
|
end
|
129
154
|
|
130
155
|
##########
|
@@ -154,6 +179,11 @@ module BubbleWrap
|
|
154
179
|
|
155
180
|
@callback.call(callback_info)
|
156
181
|
dismiss
|
182
|
+
# iPad popover? close it
|
183
|
+
if @popover
|
184
|
+
@popover.dismissPopoverAnimated(@options[:animated])
|
185
|
+
@popover = nil
|
186
|
+
end
|
157
187
|
end
|
158
188
|
|
159
189
|
##########
|
@@ -34,12 +34,22 @@ module BubbleWrap
|
|
34
34
|
def any
|
35
35
|
@any ||= BubbleWrap::Device::Camera.any
|
36
36
|
end
|
37
|
+
# alias for any
|
38
|
+
def photo_library
|
39
|
+
any
|
40
|
+
end
|
37
41
|
|
38
42
|
# Should always return true, since picking images from *some* source is always possible
|
39
43
|
# @return [TrueClass]
|
40
44
|
def any?
|
41
45
|
!!any
|
42
46
|
end
|
47
|
+
|
48
|
+
# Verifies that the device running has a physical camera.
|
49
|
+
# @return [TrueClass, FalseClass] true will be returned if the device has a physical camera, false otherwise.
|
50
|
+
def available?
|
51
|
+
BubbleWrap::Device::Camera.available?
|
52
|
+
end
|
43
53
|
end
|
44
54
|
end
|
45
55
|
end
|
data/motion/core/kvo.rb
CHANGED
@@ -21,12 +21,26 @@ module BubbleWrap
|
|
21
21
|
COLLECTION_OPERATIONS = [ NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, NSKeyValueChangeReplacement ]
|
22
22
|
DEFAULT_OPTIONS = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
|
23
23
|
|
24
|
-
def observe(
|
24
|
+
def observe(*arguments, &block)
|
25
|
+
unless [1,2].include?(arguments.length)
|
26
|
+
raise ArgumentError, "wrong number of arguments (#{arguments.length} for 1 or 2)"
|
27
|
+
end
|
28
|
+
|
29
|
+
key_path = arguments.pop
|
30
|
+
target = arguments.pop || self
|
31
|
+
|
25
32
|
target.addObserver(self, forKeyPath:key_path, options:DEFAULT_OPTIONS, context:nil) unless registered?(target, key_path)
|
26
33
|
add_observer_block(target, key_path, &block)
|
27
34
|
end
|
28
35
|
|
29
|
-
def unobserve(
|
36
|
+
def unobserve(*arguments)
|
37
|
+
unless [1,2].include?(arguments.length)
|
38
|
+
raise ArgumentError, "wrong number of arguments (#{arguments.length} for 1 or 2)"
|
39
|
+
end
|
40
|
+
|
41
|
+
key_path = arguments.pop
|
42
|
+
target = arguments.pop || self
|
43
|
+
|
30
44
|
return unless registered?(target, key_path)
|
31
45
|
|
32
46
|
target.removeObserver(self, forKeyPath:key_path)
|
@@ -54,6 +68,8 @@ module BubbleWrap
|
|
54
68
|
def add_observer_block(target, key_path, &block)
|
55
69
|
return if target.nil? || key_path.nil? || block.nil?
|
56
70
|
|
71
|
+
block.weak! if BubbleWrap.use_weak_callbacks?
|
72
|
+
|
57
73
|
@targets ||= {}
|
58
74
|
@targets[target] ||= {}
|
59
75
|
@targets[target][key_path.to_s] ||= []
|
@@ -4,6 +4,7 @@ class NSNotificationCenter
|
|
4
4
|
end
|
5
5
|
|
6
6
|
def observe(name, object=nil, &proc)
|
7
|
+
proc.weak! if proc && BubbleWrap.use_weak_callbacks?
|
7
8
|
observer = self.addObserverForName(name, object:object, queue:NSOperationQueue.mainQueue, usingBlock:proc)
|
8
9
|
observers << observer
|
9
10
|
observer
|
data/motion/core/time.rb
CHANGED
data/motion/http/query.rb
CHANGED
@@ -30,6 +30,10 @@ module BubbleWrap; module HTTP; class Query
|
|
30
30
|
def initialize(url_string, http_method = :get, options={})
|
31
31
|
@method = http_method.upcase.to_s
|
32
32
|
@delegator = options.delete(:action) || self
|
33
|
+
if @delegator.respond_to?("weak!")
|
34
|
+
@delegator.weak! if BubbleWrap.use_weak_callbacks?
|
35
|
+
end
|
36
|
+
|
33
37
|
@payload = options.delete(:payload)
|
34
38
|
@encoding = options.delete(:encoding) || NSUTF8StringEncoding
|
35
39
|
@files = options.delete(:files)
|
@@ -53,6 +57,7 @@ module BubbleWrap; module HTTP; class Query
|
|
53
57
|
@original_url = @url.copy
|
54
58
|
|
55
59
|
@connection = create_connection(request, self)
|
60
|
+
@connection.scheduleInRunLoop(NSRunLoop.currentRunLoop, forMode:NSRunLoopCommonModes)
|
56
61
|
@connection.start
|
57
62
|
|
58
63
|
show_status_indicator true
|
@@ -269,20 +274,21 @@ Cache policy: #{@cache_policy}, response: #{@response.inspect} >"
|
|
269
274
|
end
|
270
275
|
|
271
276
|
def parse_file(key, value)
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
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
|
+
}
|
278
284
|
end
|
279
285
|
|
280
286
|
def append_files(body)
|
281
287
|
@files.each do |key, value|
|
282
288
|
file = parse_file(key, value)
|
283
289
|
s = "--#{@boundary}\r\n"
|
284
|
-
s += "Content-Disposition:
|
285
|
-
s += "Content-Type:
|
290
|
+
s += "Content-Disposition: attachment; name=\"#{key}\"; filename=\"#{file[:filename]}\"\r\n"
|
291
|
+
s += "Content-Type: #{file[:content_type]}\r\n\r\n"
|
286
292
|
file_data = NSMutableData.new
|
287
293
|
file_data.appendData(s.to_encoded_data @encoding)
|
288
294
|
file_data.appendData(file[:data])
|
@@ -381,7 +387,7 @@ Cache policy: #{@cache_policy}, response: #{@response.inspect} >"
|
|
381
387
|
|
382
388
|
# This is a temporary method used for mocking.
|
383
389
|
def create_connection(request, delegate)
|
384
|
-
NSURLConnection.
|
390
|
+
NSURLConnection.alloc.initWithRequest(request, delegate:delegate, startImmediately:false)
|
385
391
|
end
|
386
392
|
|
387
393
|
end; end; end
|
data/motion/location/location.rb
CHANGED
@@ -50,6 +50,7 @@ module BubbleWrap
|
|
50
50
|
# end
|
51
51
|
def get(options = {}, &block)
|
52
52
|
@callback = block
|
53
|
+
@callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
|
53
54
|
@options = options
|
54
55
|
|
55
56
|
@options[:significant] = false if @options[:significant].nil?
|
@@ -112,11 +113,11 @@ module BubbleWrap
|
|
112
113
|
# CLLocationManagerDelegate Methods
|
113
114
|
def locationManager(manager, didUpdateToLocation:newLocation, fromLocation:oldLocation)
|
114
115
|
if @options[:once]
|
115
|
-
@callback.call(newLocation)
|
116
|
+
@callback && @callback.call(newLocation)
|
116
117
|
@callback = proc { |result| }
|
117
118
|
stop
|
118
119
|
else
|
119
|
-
@callback.call({to: newLocation, from: oldLocation})
|
120
|
+
@callback && @callback.call({to: newLocation, from: oldLocation})
|
120
121
|
end
|
121
122
|
end
|
122
123
|
|
data/motion/mail/mail.rb
CHANGED
@@ -26,11 +26,12 @@ module BubbleWrap
|
|
26
26
|
@delegate = options[:delegate] || App.window.rootViewController
|
27
27
|
|
28
28
|
@callback = callback
|
29
|
+
@callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
|
29
30
|
|
30
31
|
@mail_controller = create_mail_controller(options)
|
31
32
|
|
32
33
|
@mailer_is_animated = options[:animated] == false ? false : true
|
33
|
-
@delegate.
|
34
|
+
@delegate.presentViewController(@mail_controller, animated: @mailer_is_animated, completion: options[:completion])
|
34
35
|
end
|
35
36
|
|
36
37
|
def create_mail_controller(options={})
|