bubble-wrap 1.8.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +14 -9
  3. data/CHANGELOG.md +21 -2
  4. data/Gemfile.lock +8 -5
  5. data/README.md +54 -3
  6. data/Rakefile +7 -1
  7. data/lib/bubble-wrap/camera.rb +1 -1
  8. data/lib/bubble-wrap/core.rb +1 -1
  9. data/lib/bubble-wrap/font.rb +1 -1
  10. data/lib/bubble-wrap/loader.rb +4 -4
  11. data/lib/bubble-wrap/media.rb +1 -1
  12. data/lib/bubble-wrap/motion.rb +7 -1
  13. data/lib/bubble-wrap/version.rb +2 -2
  14. data/motion/core/app.rb +4 -0
  15. data/motion/core/device/ios/camera_wrapper.rb +1 -1
  16. data/motion/core/device/ios/screen.rb +2 -2
  17. data/motion/core/device/osx/screen.rb +1 -1
  18. data/motion/core/device/screen.rb +1 -1
  19. data/motion/core/ios/device.rb +1 -1
  20. data/motion/core/ios/ns_index_path.rb +11 -0
  21. data/motion/core/json.rb +2 -2
  22. data/motion/core/kvo.rb +118 -55
  23. data/motion/core/ns_notification_center.rb +2 -2
  24. data/motion/core/ns_url_request.rb +2 -2
  25. data/motion/core/osx/device.rb +1 -1
  26. data/motion/core/string.rb +7 -7
  27. data/motion/font/font.rb +1 -1
  28. data/motion/ios/8/location_constants.rb +21 -0
  29. data/motion/location/location.rb +38 -18
  30. data/motion/mail/result.rb +1 -1
  31. data/motion/media/media.rb +1 -1
  32. data/motion/motion/accelerometer.rb +55 -0
  33. data/motion/motion/device_motion.rb +139 -0
  34. data/motion/motion/gyroscope.rb +55 -0
  35. data/motion/motion/magnetometer.rb +55 -0
  36. data/motion/motion/motion.rb +0 -288
  37. data/motion/reactor.rb +3 -3
  38. data/motion/reactor/deferrable.rb +32 -32
  39. data/motion/reactor/periodic_timer.rb +1 -1
  40. data/motion/reactor/queue.rb +6 -6
  41. data/motion/reactor/thread_aware_deferrable.rb +1 -1
  42. data/motion/reactor/timer.rb +1 -1
  43. data/motion/rss_parser.rb +6 -3
  44. data/motion/shortcut.rb +1 -1
  45. data/motion/sms/result.rb +1 -1
  46. data/motion/test_suite_delegate.rb +1 -1
  47. data/motion/ui/ui_activity_view_controller_wrapper.rb +6 -1
  48. data/motion/ui/ui_alert_view.rb +21 -1
  49. data/motion/util/deprecated.rb +1 -1
  50. data/samples/alert/Gemfile.lock +1 -1
  51. data/spec/lib/bubble-wrap/requirement_spec.rb +2 -2
  52. data/spec/lib/bubble-wrap_spec.rb +1 -1
  53. data/spec/lib/motion_stub.rb +1 -1
  54. data/spec/motion/core/app_spec.rb +6 -0
  55. data/spec/motion/core/device/osx/screen_spec.rb +1 -1
  56. data/spec/motion/core/ios/ns_index_path_spec.rb +20 -0
  57. data/spec/motion/core/kvo_spec.rb +171 -58
  58. data/spec/motion/core/ns_notification_center_spec.rb +3 -3
  59. data/spec/motion/core/string_spec.rb +16 -16
  60. data/spec/motion/core_spec.rb +3 -3
  61. data/spec/motion/font/font_spec.rb +1 -1
  62. data/spec/motion/location/location_spec.rb +61 -9
  63. data/spec/motion/mail/result_spec.rb +7 -7
  64. data/spec/motion/media/player_spec.rb +1 -1
  65. data/spec/motion/reactor/thread_aware_deferrable_spec.rb +3 -3
  66. data/spec/motion/sms/result_spec.rb +6 -6
  67. data/spec/motion/ui/ui_alert_view_spec.rb +59 -1
  68. data/spec/motion/util/deprecated_spec.rb +1 -1
  69. metadata +17 -4
  70. data/motion/ios/7/uiactivity_view_controller_constants.rb +0 -10
@@ -15,8 +15,8 @@ class NSNotificationCenter
15
15
  removeObserver(observer)
16
16
  observers.delete(observer)
17
17
  end
18
-
18
+
19
19
  def post(name, object=nil, info=nil)
20
20
  self.postNotificationName(name, object: object, userInfo: info)
21
21
  end
22
- end
22
+ end
@@ -3,8 +3,8 @@ class NSURLRequest
3
3
  # Provides a to_s method so we can use inspect in instances and get
4
4
  # valuable information.
5
5
  def to_s
6
- "#<#{self.class}:#{self.object_id} - url: #{self.URL.description},
7
- headers: #{self.allHTTPHeaderFields.inspect},
6
+ "#<#{self.class}:#{self.object_id} - url: #{self.URL.description},
7
+ headers: #{self.allHTTPHeaderFields.inspect},
8
8
  cache policy: #{self.cachePolicy}, Pipelining: #{self.HTTPShouldUsePipelining}, main doc url: #{mainDocumentURL},\
9
9
  timeout: #{self.timeoutInterval}, network service type: #{self.networkServiceType} >"
10
10
  end
@@ -3,4 +3,4 @@ module BubbleWrap
3
3
  module_function
4
4
 
5
5
  end
6
- end
6
+ end
@@ -1,6 +1,6 @@
1
1
  module BubbleWrap
2
- # This module contains simplified version of the `camelize` and
3
- # `underscore` methods from ActiveSupport, since these are such
2
+ # This module contains simplified version of the `camelize` and
3
+ # `underscore` methods from ActiveSupport, since these are such
4
4
  # common operations when dealing with the Cocoa API.
5
5
  module String
6
6
 
@@ -67,8 +67,8 @@ module BubbleWrap
67
67
  return color_klass.send(keyword_selector) if color_klass.respond_to? keyword_selector
68
68
 
69
69
  # Next attempt to convert from hex
70
- hex_color = self.gsub("#", "")
71
- case hex_color.size
70
+ hex_color = self.gsub("#", "")
71
+ case hex_color.size
72
72
  when 3
73
73
  colors = hex_color.scan(%r{[0-9A-Fa-f]}).map!{ |el| (el * 2).to_i(16) }
74
74
  when 6
@@ -77,15 +77,15 @@ module BubbleWrap
77
77
  colors = hex_color.scan(%r<[0-9A-Fa-f]{2}>).map!{ |el| el.to_i(16) }
78
78
  else
79
79
  raise ArgumentError
80
- end
80
+ end
81
81
  if colors.size == 3
82
82
  BubbleWrap.rgb_color(colors[0], colors[1], colors[2])
83
83
  elsif colors.size == 4
84
84
  BubbleWrap.rgba_color(colors[1], colors[2], colors[3], colors[0])
85
85
  else
86
86
  raise ArgumentError
87
- end
88
- end
87
+ end
88
+ end
89
89
 
90
90
  end
91
91
  end
data/motion/font/font.rb CHANGED
@@ -82,4 +82,4 @@ module BubbleWrap
82
82
  _attributes
83
83
  end
84
84
  end
85
- end
85
+ end
@@ -0,0 +1,21 @@
1
+ module BW
2
+ # New additions to CLAuthorizationStatus in ios8
3
+ # see: https://developer.apple.com/library/prerelease/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/c/tdef/CLAuthorizationStatus
4
+ Constants.register(
5
+ KCLAuthorizationStatusAuthorized,
6
+ KCLAuthorizationStatusAuthorizedWhenInUse,
7
+ KCLAuthorizationStatusAuthorizedAlways
8
+ )
9
+
10
+ module Location
11
+ module_function
12
+
13
+ def authorized?
14
+ [
15
+ BW::Constants.get("KCLAuthorizationStatus", :authorized),
16
+ BW::Constants.get("KCLAuthorizationStatus", :authorized_always),
17
+ BW::Constants.get("KCLAuthorizationStatus", :authorized_when_in_use)
18
+ ].include?(CLLocationManager.authorizationStatus)
19
+ end
20
+ end
21
+ end
@@ -25,10 +25,6 @@ module BubbleWrap
25
25
  KCLLocationAccuracyNearestTenMeters, KCLLocationAccuracyHundredMeters,
26
26
  KCLLocationAccuracyKilometer, KCLLocationAccuracyThreeKilometers
27
27
 
28
- # New additions to CLAuthorizationStatus in ios8
29
- # see: https://developer.apple.com/library/prerelease/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/c/tdef/CLAuthorizationStatus
30
- Constants.register KCLAuthorizationStatusAuthorizedWhenInUse, KCLAuthorizationStatusAuthorizedAlways
31
-
32
28
  module_function
33
29
  # Start getting locations
34
30
  # @param [Hash] options = {
@@ -47,12 +43,15 @@ module BubbleWrap
47
43
  # }
48
44
  # @block for callback. takes one argument, `result`.
49
45
  # - On error or cancelled, is called with a hash {error: BW::Location::Error::<Type>}
50
- # - On success, is called with a hash {to: #<CLLocation>, from: #<CLLocation>}
46
+ # - On success, is called with a hash {to: #<CLLocation>, from: #<CLLocation>, previous: [#<CLLocation>,...]}
47
+ # -- :previous will return an Array of CLLocation objects, ordered from oldest to newest, excluding the
48
+ # locations :to and :from, returning an empty Array if no additional locations were provided
51
49
  #
52
50
  # Example
53
51
  # BW::Location.get(distance_filter: 10, desired_accuracy: :nearest_ten_meters) do |result|
54
52
  # result[:to].class == CLLocation
55
53
  # result[:from].class == CLLocation
54
+ # result[:previous].class == NSArray<CLLocation>
56
55
  # p "Lat #{result[:to].latitude}, Long #{result[:to].longitude}"
57
56
  # end
58
57
  def get(options = {}, &block)
@@ -70,6 +69,7 @@ module BubbleWrap
70
69
 
71
70
  @options[:significant] = false if @options[:significant].nil?
72
71
  @retries = 0
72
+ @from_location = nil
73
73
 
74
74
  if not enabled?
75
75
  error(Error::DISABLED) and return
@@ -86,13 +86,8 @@ module BubbleWrap
86
86
  self.location_manager.desiredAccuracy = Constants.get("KCLLocationAccuracy", @options[:desired_accuracy])
87
87
  self.location_manager.purpose = @options[:purpose] if @options[:purpose]
88
88
 
89
- if @options[:significant]
90
- self.location_manager.startMonitoringSignificantLocationChanges
91
- elsif @options[:compass]
92
- self.location_manager.startUpdatingHeading
93
- else
94
- self.location_manager.startUpdatingLocation
95
- end
89
+ @initialized = true
90
+ start
96
91
  end
97
92
 
98
93
  def get_significant(options = {}, &block)
@@ -136,6 +131,18 @@ module BubbleWrap
136
131
  get_compass(options.merge(once: true), &block)
137
132
  end
138
133
 
134
+ # Start getting locations
135
+ def start
136
+ return unless initialized?
137
+ if @options[:significant]
138
+ self.location_manager.startMonitoringSignificantLocationChanges
139
+ elsif @options[:compass]
140
+ self.location_manager.startUpdatingHeading
141
+ else
142
+ self.location_manager.startUpdatingLocation
143
+ end
144
+ end
145
+
139
146
  # Stop getting locations
140
147
  def stop
141
148
  return unless @options
@@ -159,9 +166,16 @@ module BubbleWrap
159
166
  CLLocationManager.locationServicesEnabled
160
167
  end
161
168
 
169
+ # returns true/false if CLLocationManager has been initialized with the provided or default options
170
+ def initialized?
171
+ @initialized ||= false
172
+ end
173
+
162
174
  # returns true/false whether services are enabled for the _app_
163
175
  def authorized?
164
- [KCLAuthorizationStatusAuthorized, KCLAuthorizationStatusAuthorizedAlways, KCLAuthorizationStatusAuthorizedWhenInUse].include?(CLLocationManager.authorizationStatus)
176
+ [
177
+ BW::Constants.get("KCLAuthorizationStatus", :authorized)
178
+ ].include?(CLLocationManager.authorizationStatus)
165
179
  end
166
180
 
167
181
  def error(type)
@@ -172,13 +186,19 @@ module BubbleWrap
172
186
 
173
187
  ##########
174
188
  # CLLocationManagerDelegate Methods
175
- def locationManager(manager, didUpdateToLocation:newLocation, fromLocation:oldLocation)
189
+ def locationManager(manager, didUpdateLocations:locations)
176
190
  if @options[:once]
177
- @callback && @callback.call(newLocation)
191
+ @callback && @callback.call(locations.last)
178
192
  @callback = proc { |result| }
179
193
  stop
180
194
  else
181
- @callback && @callback.call({to: newLocation, from: oldLocation})
195
+ size = locations.count
196
+ result = {to: locations.last,
197
+ from: ( (size > 1) ? locations.last(2).first : @from_location ),
198
+ previous: ( (size > 2) ? locations.first(size - 2) : [] )
199
+ }
200
+ @from_location = result[:to]
201
+ @callback && @callback.call(result)
182
202
  end
183
203
  end
184
204
 
@@ -211,8 +231,8 @@ module BubbleWrap
211
231
  if @retries > @options[:retries]
212
232
  error(Error::LOCATION_UNKNOWN)
213
233
  else
214
- self.location_manager.stopUpdatingLocation
215
- self.location_manager.startUpdatingLocation
234
+ stop
235
+ start
216
236
  end
217
237
  when KCLErrorNetwork
218
238
  error(Error::NETWORK_FAILURE)
@@ -23,7 +23,7 @@ module BubbleWrap
23
23
  def failed?
24
24
  self.result == MFMailComposeResultFailed || self.error
25
25
  end
26
-
26
+
27
27
  end
28
28
  end
29
29
  end
@@ -12,4 +12,4 @@ module BubbleWrap
12
12
  end
13
13
  end
14
14
 
15
- ::Media = BubbleWrap::Media unless defined?(::Media)
15
+ ::Media = BubbleWrap::Media unless defined?(::Media)
@@ -0,0 +1,55 @@
1
+ module BubbleWrap
2
+ module Motion
3
+ class Accelerometer < GenericMotionInterface
4
+
5
+ def start(options={}, &handler)
6
+ if options.key?(:interval)
7
+ @manager.accelerometerUpdateInterval = options[:interval]
8
+ end
9
+
10
+ if handler
11
+ queue = convert_queue(options[:queue])
12
+ @manager.startAccelerometerUpdatesToQueue(queue, withHandler: internal_handler(handler))
13
+ else
14
+ @manager.startAccelerometerUpdates
15
+ end
16
+
17
+ return self
18
+ end
19
+
20
+ private def handle_result(result_data, error, handler)
21
+ if result_data
22
+ result = {
23
+ data: result_data,
24
+ acceleration: result_data.acceleration,
25
+ x: result_data.acceleration.x,
26
+ y: result_data.acceleration.y,
27
+ z: result_data.acceleration.z,
28
+ }
29
+ else
30
+ result = nil
31
+ end
32
+
33
+ handler.call(result, error)
34
+ end
35
+
36
+ def available?
37
+ @manager.accelerometerAvailable?
38
+ end
39
+
40
+ def active?
41
+ @manager.accelerometerActive?
42
+ end
43
+
44
+ def data
45
+ @manager.accelerometerData
46
+ end
47
+
48
+ def stop
49
+ @manager.stopAccelerometerUpdates
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,139 @@
1
+ module BubbleWrap
2
+ module Motion
3
+ class DeviceMotion < GenericMotionInterface
4
+
5
+ def start(options={}, &handler)
6
+ if options.key?(:interval)
7
+ @manager.deviceMotionUpdateInterval = options[:interval]
8
+ end
9
+
10
+ if options.key?(:reference)
11
+ reference_frame = convert_reference_frame(options[:reference])
12
+ else
13
+ reference_frame = nil
14
+ end
15
+
16
+ if handler
17
+ queue = convert_queue(options[:queue])
18
+
19
+ if reference_frame
20
+ @manager.startDeviceMotionUpdatesUsingReferenceFrame(reference_frame, toQueue: queue, withHandler: internal_handler(handler))
21
+ else
22
+ @manager.startDeviceMotionUpdatesToQueue(queue, withHandler: internal_handler(handler))
23
+ end
24
+ else
25
+ if reference_frame
26
+ @manager.startDeviceMotionUpdatesUsingReferenceFrame(reference_frame)
27
+ else
28
+ @manager.startDeviceMotionUpdates
29
+ end
30
+ end
31
+
32
+ return self
33
+ end
34
+
35
+ private def handle_result(result_data, error, handler)
36
+ if result_data
37
+ result = {
38
+ data: result_data,
39
+ attitude: result_data.attitude,
40
+ rotation: result_data.rotationRate,
41
+ gravity: result_data.gravity,
42
+ acceleration: result_data.userAcceleration,
43
+ magnetic: result_data.magneticField,
44
+ }
45
+
46
+ if result_data.attitude
47
+ result.merge!({
48
+ roll: result_data.attitude.roll,
49
+ pitch: result_data.attitude.pitch,
50
+ yaw: result_data.attitude.yaw,
51
+ matrix: result_data.attitude.rotationMatrix,
52
+ quaternion: result_data.attitude.quaternion,
53
+ })
54
+ end
55
+
56
+ if result_data.rotationRate
57
+ result.merge!({
58
+ rotation_x: result_data.rotationRate.x,
59
+ rotation_y: result_data.rotationRate.y,
60
+ rotation_z: result_data.rotationRate.z,
61
+ })
62
+ end
63
+
64
+ if result_data.gravity
65
+ result.merge!({
66
+ gravity_x: result_data.gravity.x,
67
+ gravity_y: result_data.gravity.y,
68
+ gravity_z: result_data.gravity.z,
69
+ })
70
+ end
71
+
72
+ if result_data.userAcceleration
73
+ result.merge!({
74
+ acceleration_x: result_data.userAcceleration.x,
75
+ acceleration_y: result_data.userAcceleration.y,
76
+ acceleration_z: result_data.userAcceleration.z,
77
+ })
78
+ end
79
+
80
+ if result_data.magneticField
81
+ case result_data.magneticField.accuracy
82
+ when CMMagneticFieldCalibrationAccuracyLow
83
+ accuracy = :low
84
+ when CMMagneticFieldCalibrationAccuracyMedium
85
+ accuracy = :medium
86
+ when CMMagneticFieldCalibrationAccuracyHigh
87
+ accuracy = :high
88
+ end
89
+
90
+ result.merge!({
91
+ field: result_data.magneticField.field,
92
+ magnetic_x: result_data.magneticField.field.x,
93
+ magnetic_y: result_data.magneticField.field.y,
94
+ magnetic_z: result_data.magneticField.field.z,
95
+ magnetic_accuracy: accuracy,
96
+ })
97
+ end
98
+ else
99
+ result = nil
100
+ end
101
+
102
+ handler.call(result, error)
103
+ end
104
+
105
+ def convert_reference_frame(reference_frame)
106
+ case reference_frame
107
+ when :arbitrary_z
108
+ CMAttitudeReferenceFrameXArbitraryZVertical
109
+ when :corrected_z
110
+ CMAttitudeReferenceFrameXArbitraryCorrectedZVertical
111
+ when :magnetic_north
112
+ CMAttitudeReferenceFrameXMagneticNorthZVertical
113
+ when :true_north
114
+ CMAttitudeReferenceFrameXTrueNorthZVertical
115
+ else
116
+ reference_frame
117
+ end
118
+ end
119
+
120
+ def available?
121
+ @manager.deviceMotionAvailable?
122
+ end
123
+
124
+ def active?
125
+ @manager.deviceMotionActive?
126
+ end
127
+
128
+ def data
129
+ @manager.deviceMotion
130
+ end
131
+
132
+ def stop
133
+ @manager.stopDeviceMotionUpdates
134
+ end
135
+
136
+ end
137
+
138
+ end
139
+ end
@@ -0,0 +1,55 @@
1
+ module BubbleWrap
2
+ module Motion
3
+ class Gyroscope < GenericMotionInterface
4
+
5
+ def start(options={}, &handler)
6
+ if options.key?(:interval)
7
+ @manager.gyroUpdateInterval = options[:interval]
8
+ end
9
+
10
+ if handler
11
+ queue = convert_queue(options[:queue])
12
+ @manager.startGyroUpdatesToQueue(queue, withHandler: internal_handler(handler))
13
+ else
14
+ @manager.startGyroUpdates
15
+ end
16
+
17
+ return self
18
+ end
19
+
20
+ private def handle_result(result_data, error, handler)
21
+ if result_data
22
+ result = {
23
+ data: result_data,
24
+ rotation: result_data.rotationRate,
25
+ x: result_data.rotationRate.x,
26
+ y: result_data.rotationRate.y,
27
+ z: result_data.rotationRate.z,
28
+ }
29
+ else
30
+ result = nil
31
+ end
32
+
33
+ handler.call(result, error)
34
+ end
35
+
36
+ def available?
37
+ @manager.gyroAvailable?
38
+ end
39
+
40
+ def active?
41
+ @manager.gyroActive?
42
+ end
43
+
44
+ def data
45
+ @manager.gyroData
46
+ end
47
+
48
+ def stop
49
+ @manager.stopGyroUpdates
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end