bubble-wrap 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/README.md +183 -66
- data/Rakefile +6 -6
- data/bubble-wrap.gemspec +10 -5
- data/lib/bubble-wrap.rb +4 -39
- data/lib/bubble-wrap/core.rb +7 -0
- data/lib/bubble-wrap/ext.rb +2 -0
- data/lib/bubble-wrap/ext/motion_project_app.rb +26 -0
- data/lib/bubble-wrap/ext/motion_project_config.rb +21 -0
- data/lib/bubble-wrap/http.rb +2 -249
- data/lib/bubble-wrap/loader.rb +23 -0
- data/lib/bubble-wrap/requirement.rb +88 -0
- data/lib/bubble-wrap/requirement/path_manipulation.rb +40 -0
- data/lib/bubble-wrap/version.rb +1 -1
- data/lib_spec/bubble-wrap/requirement/path_manipulation_spec.rb +51 -0
- data/lib_spec/bubble-wrap/requirement_spec.rb +72 -0
- data/lib_spec/bubble-wrap_spec.rb +17 -0
- data/lib_spec/motion_stub.rb +12 -0
- data/{lib/bubble-wrap/module.rb → motion/core.rb} +0 -0
- data/{lib/bubble-wrap → motion/core}/app.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/device.rb +0 -16
- data/{lib/bubble-wrap → motion/core}/device/screen.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/gestures.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/json.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ns_index_path.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ns_notification_center.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ns_user_defaults.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/persistence.rb +0 -0
- data/{lib → motion/core}/pollute.rb +1 -1
- data/motion/core/string.rb +38 -0
- data/{lib/bubble-wrap → motion/core}/time.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ui_control.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ui_view_controller.rb +0 -0
- data/motion/http.rb +249 -0
- data/spec/{app_spec.rb → core/app_spec.rb} +2 -2
- data/spec/{device → core/device}/screen_spec.rb +0 -0
- data/spec/{device_spec.rb → core/device_spec.rb} +0 -0
- data/spec/{gestures_spec.rb → core/gestures_spec.rb} +0 -0
- data/spec/{json_spec.rb → core/json_spec.rb} +0 -0
- data/spec/{ns_index_path_spec.rb → core/ns_index_path_spec.rb} +0 -0
- data/spec/{ns_notification_center_spec.rb → core/ns_notification_center_spec.rb} +0 -0
- data/spec/{persistence_spec.rb → core/persistence_spec.rb} +0 -0
- data/spec/core/string_spec.rb +69 -0
- data/spec/{time_spec.rb → core/time_spec.rb} +0 -0
- data/spec/{ui_control_spec.rb → core/ui_control_spec.rb} +0 -0
- data/spec/{module_spec.rb → core_spec.rb} +0 -0
- data/spec/http_spec.rb +300 -280
- metadata +115 -42
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# BubbleWrap for RubyMotion
|
2
2
|
|
3
|
-
A collection of helpers and wrappers used to wrap CocoaTouch code and provide more Ruby like APIs.
|
3
|
+
A collection of (tested) helpers and wrappers used to wrap CocoaTouch code and provide more Ruby like APIs.
|
4
|
+
|
5
|
+
[BubbleWrap website](http://bubblewrap.io)
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -10,80 +12,50 @@ gem install bubble-wrap
|
|
10
12
|
|
11
13
|
## Setup
|
12
14
|
|
13
|
-
1. Edit the Rakefile of your RubyMotion project and add the following require line.
|
15
|
+
1. Edit the `Rakefile` of your RubyMotion project and add the following require line.
|
16
|
+
|
14
17
|
```ruby
|
15
18
|
require 'bubble-wrap'
|
16
19
|
```
|
17
|
-
Note: **DON'T** use `app.files =` in your Rakefile to set up your files once you've required BubbleWrap.
|
18
|
-
Make sure to append onto the array or use `+=`.
|
19
20
|
|
20
|
-
|
21
|
+
BubbleWrap is split into multiple modules so that you can easily choose which parts
|
22
|
+
are included at compile-time.
|
23
|
+
|
24
|
+
The above example requires all the wrappers/helpers. If you wish to only
|
25
|
+
include the core modules use the following line of code instead:
|
21
26
|
|
22
27
|
```ruby
|
23
|
-
|
24
|
-
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
25
|
-
puts "#{App.name} (#{documents_path})"
|
26
|
-
true
|
27
|
-
end
|
28
|
-
end
|
28
|
+
require 'bubble-wrap/core'
|
29
29
|
```
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
## HTTP
|
34
|
-
|
35
|
-
`BubbleWrap::HTTP` wraps `NSURLRequest`, `NSURLConnection` and friends to provide Ruby developers with a more familiar and easier to use API.
|
36
|
-
The API uses async calls and blocks to stay as simple as possible.
|
37
|
-
|
38
|
-
Usage example:
|
31
|
+
If you wish to only include the `HTTP` wrapper:
|
39
32
|
|
40
33
|
```ruby
|
41
|
-
|
42
|
-
p response.body.to_str
|
43
|
-
end
|
34
|
+
require 'bubble-wrap/http'
|
44
35
|
```
|
45
36
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
37
|
+
|
38
|
+
Note: **DON'T** use `app.files =` in your Rakefile to set up your files once you've required BubbleWrap.
|
39
|
+
Make sure to append onto the array or use `+=`.
|
40
|
+
|
41
|
+
2. Now, you can use BubbleWrap extension in your app:
|
51
42
|
|
52
43
|
```ruby
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
p json['id']
|
58
|
-
elsif response.status_code.to_s =~ /40\d/
|
59
|
-
alert("Login failed") # helper provided by the kernel file in this repo.
|
60
|
-
else
|
61
|
-
alert(response.error_message)
|
44
|
+
class AppDelegate
|
45
|
+
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
46
|
+
puts "#{App.name} (#{documents_path})"
|
47
|
+
true
|
62
48
|
end
|
63
49
|
end
|
64
50
|
```
|
65
51
|
|
66
|
-
|
52
|
+
Note: You can also vendor this repository but the recommended way is to
|
53
|
+
use the versioned gem.
|
67
54
|
|
68
|
-
`BubbleWrap::JSON` wraps `NSJSONSerialization` available in iOS5 and offers the same API as Ruby's JSON std lib.
|
69
|
-
|
70
|
-
## Device
|
71
55
|
|
72
|
-
|
73
|
-
|
74
|
-
Examples:
|
75
|
-
```ruby
|
76
|
-
> Device.iphone?
|
77
|
-
# true
|
78
|
-
> Device.ipad?
|
79
|
-
# false
|
80
|
-
> Device.orientation
|
81
|
-
# :portrait
|
82
|
-
> Device.simulator?
|
83
|
-
# true
|
84
|
-
```
|
56
|
+
## Core
|
85
57
|
|
86
|
-
|
58
|
+
### App
|
87
59
|
|
88
60
|
A module with useful methods related to the running application
|
89
61
|
|
@@ -100,18 +72,53 @@ A module with useful methods related to the running application
|
|
100
72
|
# creates and shows an alert message.
|
101
73
|
> App.run_after(0.5) { p "It's #{Time.now}" }
|
102
74
|
# Runs the block after 0.5 seconds.
|
75
|
+
> App::Persistence['channels'] # application specific persistence storage
|
76
|
+
# ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
|
77
|
+
> App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
|
78
|
+
# ['TF1', 'France 2', 'France 3']
|
103
79
|
```
|
104
80
|
|
105
|
-
|
81
|
+
Other available methods:
|
106
82
|
|
107
|
-
|
83
|
+
* `App.notification_center`
|
84
|
+
* `App.user_cache`
|
85
|
+
* `App.states`
|
86
|
+
* `App.frame`
|
87
|
+
* `App.delegate`
|
88
|
+
* `App.current_locale`
|
108
89
|
|
109
|
-
## NSIndexPath
|
110
90
|
|
111
|
-
|
112
|
-
|
91
|
+
### Device
|
92
|
+
|
93
|
+
A collection of useful methods about the current device:
|
94
|
+
|
95
|
+
Examples:
|
96
|
+
```ruby
|
97
|
+
> Device.iphone?
|
98
|
+
# true
|
99
|
+
> Device.ipad?
|
100
|
+
# false
|
101
|
+
> Device.front_camera?
|
102
|
+
# true
|
103
|
+
> Device.rear_camera?
|
104
|
+
# true
|
105
|
+
> Device.orientation
|
106
|
+
# :portrait
|
107
|
+
> Device.simulator?
|
108
|
+
# true
|
109
|
+
> Device.retina?
|
110
|
+
# false
|
111
|
+
> Device.screen.width
|
112
|
+
# 320
|
113
|
+
> Device.screen.height
|
114
|
+
# 480
|
115
|
+
> Device.screen.widthForOrientation(:landscape_left)
|
116
|
+
# 480
|
117
|
+
> Device.screen.heightForOrientation(:landscape_left)
|
118
|
+
# 320
|
119
|
+
```
|
113
120
|
|
114
|
-
|
121
|
+
### Gestures
|
115
122
|
|
116
123
|
Extra methods on `UIView` for working with gesture recognizers. A gesture recognizer can be added using a normal Ruby block, like so:
|
117
124
|
|
@@ -127,17 +134,26 @@ Extra methods on `UIView` for working with gesture recognizers. A gesture recogn
|
|
127
134
|
|
128
135
|
There are similar methods for pinched, rotated, swiped, panned, and pressed (for long presses). All of the methods return the actual recognizer object, so it is possible to set the delegate if more fine-grained control is needed.
|
129
136
|
|
130
|
-
## UIButton
|
131
137
|
|
132
|
-
|
138
|
+
|
139
|
+
### JSON
|
140
|
+
|
141
|
+
`BubbleWrap::JSON` wraps `NSJSONSerialization` available in iOS5 and offers the same API as Ruby's JSON std lib.
|
133
142
|
|
134
143
|
```ruby
|
135
|
-
|
136
|
-
|
137
|
-
|
144
|
+
BW::JSON.generate({'foo => 1, 'bar' => [1,2,3], 'baz => 'awesome'})
|
145
|
+
=> "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
|
146
|
+
BW::JSON.parse "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
|
147
|
+
=> {"foo"=>1, "bar"=>[1, 2, 3], "baz"=>"awesome"}
|
138
148
|
```
|
139
149
|
|
140
|
-
|
150
|
+
### NSIndexPath
|
151
|
+
|
152
|
+
Helper methods added to give `NSIndexPath` a bit more of a Ruby
|
153
|
+
interface.
|
154
|
+
|
155
|
+
|
156
|
+
### NSNotificationCenter
|
141
157
|
|
142
158
|
Helper methods to give NSNotificationCenter a Ruby-like interface:
|
143
159
|
|
@@ -161,3 +177,104 @@ def reload
|
|
161
177
|
notification_center.post ReloadNotification
|
162
178
|
end
|
163
179
|
```
|
180
|
+
|
181
|
+
|
182
|
+
### NSUserDefaults
|
183
|
+
|
184
|
+
Helper methods added to the class repsonsible for user preferences used
|
185
|
+
by the `App::Persistence` module shown below.
|
186
|
+
|
187
|
+
### Persistence
|
188
|
+
|
189
|
+
Offers a way to persist application specific information using a very
|
190
|
+
simple interface:
|
191
|
+
|
192
|
+
``` ruby
|
193
|
+
> App::Persistence['channels'] # application specific persistence storage
|
194
|
+
# ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
|
195
|
+
> App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
|
196
|
+
# ['TF1', 'France 2', 'France 3']
|
197
|
+
```
|
198
|
+
|
199
|
+
### String
|
200
|
+
|
201
|
+
The Ruby `String` class was extended to add `#camelize` and
|
202
|
+
`#underscore` methods.
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
> "matt_aimonetti".camelize
|
206
|
+
=> "MattAimonetti"
|
207
|
+
> "MattAimonetti".underscore
|
208
|
+
=> "matt_aimonetti"
|
209
|
+
```
|
210
|
+
|
211
|
+
### Time
|
212
|
+
|
213
|
+
The `Time` Ruby class was added a class level method to convert a
|
214
|
+
iso8601 formatted string into a Time instance.
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
> Time.iso8601("2012-05-31T19:41:33Z")
|
218
|
+
=> 2012-05-31 21:41:33 +0200
|
219
|
+
```
|
220
|
+
|
221
|
+
### UIControl / UIButton
|
222
|
+
|
223
|
+
Helper methods to give `UIButton` a Ruby-like interface. Ex:
|
224
|
+
|
225
|
+
```ruby
|
226
|
+
button.when(UIControlEventTouchUpInside) do
|
227
|
+
self.view.backgroundColor = UIColor.redColor
|
228
|
+
end
|
229
|
+
```
|
230
|
+
|
231
|
+
### UIViewController
|
232
|
+
|
233
|
+
A custom method was added to `UIViewController` to return the content
|
234
|
+
frame of a view controller.
|
235
|
+
|
236
|
+
|
237
|
+
## HTTP
|
238
|
+
|
239
|
+
`BubbleWrap::HTTP` wraps `NSURLRequest`, `NSURLConnection` and friends to provide Ruby developers with a more familiar and easier to use API.
|
240
|
+
The API uses async calls and blocks to stay as simple as possible.
|
241
|
+
|
242
|
+
To enable it add the following require line to your `Rakefile`:
|
243
|
+
```ruby
|
244
|
+
require 'bubble-wrap/http'
|
245
|
+
```
|
246
|
+
|
247
|
+
Usage example:
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
BubbleWrap::HTTP.get("https://api.github.com/users/mattetti") do |response|
|
251
|
+
p response.body.to_str
|
252
|
+
end
|
253
|
+
```
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
BubbleWrap::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
|
257
|
+
p response.body.to_str # prints the response's body
|
258
|
+
end
|
259
|
+
```
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
data = {first_name: 'Matt', last_name: 'Aimonetti'}
|
263
|
+
BubbleWrap::HTTP.post("http://foo.bar.com/", {payload: data}) do |response|
|
264
|
+
if response.ok?
|
265
|
+
json = BubbleWrap::JSON.parse(response.body.to_str)
|
266
|
+
p json['id']
|
267
|
+
elsif response.status_code.to_s =~ /40\d/
|
268
|
+
alert("Login failed") # helper provided by the kernel file in this repo.
|
269
|
+
else
|
270
|
+
alert(response.error_message)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
```
|
274
|
+
|
275
|
+
|
276
|
+
|
277
|
+
Do you have a suggestion for a specific wrapper? Feel free to open an
|
278
|
+
issue/ticket and tell us about what you are after. If you have a
|
279
|
+
wrapper/helper you are using and are thinking that others might enjoy,
|
280
|
+
please send a pull request (with tests if possible).
|
data/Rakefile
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
$:.unshift("/Library/RubyMotion/lib")
|
3
3
|
require 'motion/project'
|
4
|
+
require File.expand_path '../lib/bubble-wrap', __FILE__
|
5
|
+
require File.expand_path '../lib/bubble-wrap/http', __FILE__
|
6
|
+
|
7
|
+
task :rspec do
|
8
|
+
sh "rspec lib_spec/"
|
9
|
+
end
|
4
10
|
|
5
11
|
Motion::Project::App.setup do |app|
|
6
12
|
app.name = 'testSuite'
|
@@ -10,10 +16,4 @@ Motion::Project::App.setup do |app|
|
|
10
16
|
app.files << './lib/tests/test_suite_delegate.rb'
|
11
17
|
app.delegate_class = 'TestSuiteDelegate'
|
12
18
|
end
|
13
|
-
|
14
|
-
app.files += Dir.glob('./lib/bubble-wrap/**/*.rb')
|
15
|
-
wrapper_files = app.files.dup
|
16
|
-
pollution_file = Dir.glob('./lib/pollute.rb')[0]
|
17
|
-
app.files << pollution_file
|
18
|
-
app.files_dependencies pollution_file => wrapper_files
|
19
19
|
end
|
data/bubble-wrap.gemspec
CHANGED
@@ -2,15 +2,20 @@
|
|
2
2
|
require File.expand_path('../lib/bubble-wrap/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = ["Matt Aimonetti", "Francis Chong"]
|
6
|
-
gem.email = ["mattaimonetti@gmail.com", "francis@ignition.hk"]
|
5
|
+
gem.authors = ["Matt Aimonetti", "Francis Chong", "James Harton"]
|
6
|
+
gem.email = ["mattaimonetti@gmail.com", "francis@ignition.hk", "james@sociable.co.nz"]
|
7
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
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 = "
|
9
|
+
gem.homepage = "http://bubblewrap.io/"
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
12
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|lib_spec|features)/})
|
13
13
|
gem.name = "bubble-wrap"
|
14
14
|
gem.require_paths = ["lib"]
|
15
15
|
gem.version = BubbleWrap::VERSION
|
16
|
-
|
16
|
+
|
17
|
+
gem.extra_rdoc_files = gem.files.grep(%r{motion})
|
18
|
+
|
19
|
+
gem.add_development_dependency 'rspec'
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
end
|
data/lib/bubble-wrap.rb
CHANGED
@@ -1,39 +1,4 @@
|
|
1
|
-
require "bubble-wrap/version"
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
module Motion
|
8
|
-
module Project
|
9
|
-
class Config
|
10
|
-
# HACK NEEDED since RubyMotion doesn't support full path
|
11
|
-
# dependencies.
|
12
|
-
def files_dependencies(deps_hash)
|
13
|
-
res_path = lambda do |x|
|
14
|
-
path = /^\.?\//.match(x) ? x : File.join('.', x)
|
15
|
-
unless @files.include?(path)
|
16
|
-
App.fail "Can't resolve dependency `#{x}' because #{path} is not in #{@files.inspect}"
|
17
|
-
end
|
18
|
-
path
|
19
|
-
end
|
20
|
-
deps_hash.each do |path, deps|
|
21
|
-
deps = [deps] unless deps.is_a?(Array)
|
22
|
-
@dependencies[res_path.call(path)] = deps.map(&res_path)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
Motion::Project::App.setup do |app|
|
31
|
-
wrapper_files = []
|
32
|
-
Dir.glob(File.join(File.dirname(__FILE__), 'bubble-wrap/**/*.rb')).each do |file|
|
33
|
-
app.files << file
|
34
|
-
wrapper_files << file
|
35
|
-
end
|
36
|
-
pollution_file = File.expand_path(File.join(File.dirname(__FILE__), 'pollute.rb'))
|
37
|
-
app.files.unshift pollution_file
|
38
|
-
app.files_dependencies pollution_file => wrapper_files
|
39
|
-
end
|
1
|
+
require "bubble-wrap/version" unless defined?(BubbleWrap::VERSION)
|
2
|
+
require File.expand_path('../bubble-wrap/loader', __FILE__)
|
3
|
+
require File.expand_path('../bubble-wrap/core', __FILE__)
|
4
|
+
require File.expand_path('../bubble-wrap/http', __FILE__)
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require File.expand_path('../loader.rb', __FILE__)
|
2
|
+
BubbleWrap.require('motion/core.rb')
|
3
|
+
BubbleWrap.require('motion/core/**/*.rb') do
|
4
|
+
file('motion/core/device/screen.rb').depends_on 'motion/core/device.rb'
|
5
|
+
file('motion/core/pollute.rb').depends_on 'motion/core/ns_index_path.rb'
|
6
|
+
file('motion/core/pollute.rb').depends_on 'motion/core/ui_control.rb'
|
7
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module BubbleWrap
|
2
|
+
module Ext
|
3
|
+
module BuildTask
|
4
|
+
|
5
|
+
def self.extended(base)
|
6
|
+
base.instance_eval do
|
7
|
+
def setup_with_bubblewrap(&block)
|
8
|
+
bw_config = proc do |app|
|
9
|
+
app.files = ::BubbleWrap::Requirement.files + Dir.glob('./app/**/*.rb')
|
10
|
+
app.files_dependencies ::BubbleWrap::Requirement.files_dependencies
|
11
|
+
app.frameworks = ::BubbleWrap::Requirement.frameworks
|
12
|
+
block.call(app)
|
13
|
+
end
|
14
|
+
configs.each_value &bw_config
|
15
|
+
config.validate
|
16
|
+
end
|
17
|
+
alias :setup_without_bubblewrap :setup
|
18
|
+
alias :setup :setup_with_bubblewrap
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Motion::Project::App.extend(BubbleWrap::Ext::BuildTask)
|