bubble-wrap 1.4.0 → 1.5.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.
- 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={})
|