motional 0.1.0

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.
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .repl_history
19
+ build
20
+ .DS_Store
@@ -0,0 +1,5 @@
1
+ language: objective-c
2
+ before_install: rvm use ruby-1.9.3-p392
3
+ script:
4
+ - bundle exec rake spec files=spec_helper
5
+ - bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in motional.gemspec
4
+ gemspec
@@ -0,0 +1,13 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'motion' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+
7
+ # RubyMotion App example
8
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
9
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
10
+
11
+ # RubyMotion gem example
12
+ watch(%r{^lib/[^/]+/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 akahige
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,128 @@
1
+ # MotionAL
2
+
3
+ AssetLibrary framework wrapper for RubyMotion.
4
+
5
+ *This gem is a beta quality.*
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'motional'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ ## Setup
18
+
19
+ Add this code to your application's Rakefile.
20
+
21
+ require 'bundler'
22
+ Bundler.require(:development)
23
+
24
+ ## Overview
25
+
26
+ ### Library
27
+
28
+ # singleton for the lifetime.
29
+ library = MotionAL.library # should not call `Motional::Library.new` directly.
30
+
31
+ library.groups # An alias of MotionAL::Group
32
+ library.groups.each do |group|
33
+ # asynchronous
34
+ # enumerate all groups except Photo Library
35
+ end
36
+
37
+ # open Camera Roll
38
+ library.groups.find_camera_roll do |group|
39
+ # asynchronous
40
+ group.assets.each do |asset|
41
+ # enumerate all assets in the camera roll
42
+ end
43
+ end
44
+
45
+ # open Photo Library synced from itunes
46
+ library.groups.find_photo_library {|group| ... # asynchronous }
47
+
48
+ library.al_asset_library # An instance of ALAssetLibrary
49
+
50
+ MotionAL.authorized? # check permission to access Asset Library. see Settings > Privacy > Photos
51
+
52
+ ### Group
53
+
54
+ MotionAL::Group.create('MyAppAlbum') do |group|
55
+ # asynchronous
56
+ group.name #=> 'MyAppAlbum'
57
+ group.url.absoluteString # save this to permanent strage
58
+ end
59
+
60
+ MotionAL::Group.find_by_url(saved_url_absolute_string) do |group|
61
+ # accept NSURL or String
62
+ # asynchronous
63
+ p group.name #=> 'MyAppAlbum'
64
+ end
65
+
66
+ group.assets # An instance of MotionAL::Assets
67
+ group.assets.each {|asset| ... # asynchronous }
68
+ group.assets.create(image_data, metadata) {|asset| ... # asynchronous } # create asset and add to the group
69
+ group.assets << some_asset # an asset add to the group.
70
+
71
+ group.al_asset_group # An instance of ALAssetGroup
72
+
73
+ ### Asset
74
+
75
+ MotionAL::Asset.create(image_data, metadata) do |asset|
76
+ asset.url.absoluteString # save this to permanent strage
77
+ end
78
+
79
+ MotionAL::Asset.find_by_url(saved_url_absolute_string) {|asset| ... # asynchronous }
80
+
81
+ asset.representations # An instance of Representations
82
+ asset.representations.each {|rep| ... # not asynchronous }
83
+
84
+ asset.default_representation # An instance of MotionAL::Representation for default representation.
85
+
86
+ # properties
87
+ asset.location
88
+ asset.media_type # :photo or :video
89
+ MotionAL.asset_types(asset.media_type) # to get objective-c constant value
90
+ asset.orientation # :up, :down, :left...
91
+ MotionAL.asset_orientations(asset.orientation) # to get objective-c constant value
92
+
93
+ # default representation properties
94
+ asset.filename
95
+ asset.metadata
96
+ asset.full_resolution_image
97
+ asset.full_screen_image
98
+
99
+ asset.al_asset # An instance of ALAsset
100
+
101
+ ### Representation
102
+
103
+ # properties
104
+ rep.filename
105
+ rep.metadata
106
+ rep.full_resolution_image
107
+ rep.full_screen_image
108
+
109
+ rep.al_asset_representation # An instance of ALAssetRepresentation
110
+
111
+ ## How to run specs
112
+
113
+ ### Preparing test data
114
+
115
+ rake spec files=spec_helper
116
+
117
+ ### Run specs
118
+
119
+ rake spec
120
+
121
+ ## Contributing
122
+
123
+ 1. Fork it
124
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
125
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
126
+ 4. Check all specs passed on your simurator (`rake spec`)
127
+ 5. Push to the branch (`git push origin my-new-feature`)
128
+ 6. Create new Pull Request
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ $:.unshift("/Library/RubyMotion/lib")
4
+ $:.unshift("#{File.dirname(__FILE__)}/lib")
5
+ require 'motion/project/template/ios'
6
+ require 'bundler'
7
+
8
+ Bundler.require(:development)
9
+
10
+ require 'motional'
11
+
12
+ Motion::Project::App.setup do |app|
13
+ app.name = 'MotionAL'
14
+ app.redgreen_style = :full # :focused, :full
15
+ end
@@ -0,0 +1,14 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ # for testing
4
+ class AppDelegate
5
+ def application(application, didFinishLaunchingWithOptions: launchOptions)
6
+ true
7
+ end
8
+
9
+ def test_image
10
+ @path = "#{NSBundle.mainBundle.resourcePath}/sample.jpg"
11
+ @url = NSURL.fileURLWithPath(@path)
12
+ cg_image_source = CGImageSourceCreateWithURL(@url, nil);
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ # -*- encoding : utf-8 -*-
2
+ unless defined?(Motion::Project::Config)
3
+ raise "This file must be required within a RubyMotion project Rakefile."
4
+ end
5
+
6
+ Motion::Project::App.setup do |app|
7
+ app.frameworks += ['AssetsLibrary', 'ImageIO']
8
+ Dir.glob(File.join(File.dirname(__FILE__), 'motional/*rb')).each do |file|
9
+ app.files.unshift(file)
10
+ end
11
+ end
@@ -0,0 +1,426 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module MotionAL
4
+ #
5
+ # A wrapper of ALAsset class.
6
+ #
7
+ # An ALAsset object represents a photo or a video managed by the Photo application.
8
+ # Assets can have multiple representations, for example a photo which was captured in RAW and JPG. Different representations of the same asset may have different dimensions.
9
+ #
10
+ # And added some convinience methods.
11
+ #
12
+ class Asset
13
+ # An instance of ALAsset.
14
+ attr_reader :al_asset
15
+
16
+ # @param al_asset [ALAsset]
17
+ def initialize(al_asset)
18
+ @al_asset = al_asset
19
+ end
20
+
21
+ # @return [MotionAL::Representations] The collection of representations in the asset.
22
+ def representations
23
+ @representations ||= Representations.new(self)
24
+ end
25
+
26
+ # Create an asset.
27
+ #
28
+ # @param source [CGImage, NSData, NSURL] CGImage and NSData for the photo, NSURL for the video.
29
+ # @param metadata [Hash] Metadata for the photo.
30
+ # @return [nil]
31
+ #
32
+ # @yield [asset, error]
33
+ # @yieldparam asset [MotionAL::Asset] A created asset.
34
+ # @yieldparam error [error]
35
+ #
36
+ # @note use `MotionAL::Asset.video_compatible?(video_path_url)` before creating video.
37
+ #
38
+ # @example
39
+ # MotionAL::Asset.create(data, meta) do |asset, error|
40
+ # # asynchronous if a block given
41
+ # p asset.url.absoluteString
42
+ # end
43
+ #
44
+ # MotionAL::Asset.create(data, meta)
45
+ #
46
+ # if MotionAL::Asset.video_compatible?(video_path_url)
47
+ # MotionAL::Asset.create(data, meta)
48
+ # else
49
+ # p "This video contained incompatible data."
50
+ # end
51
+ def self.create(source, metadata = nil, &block)
52
+ if source.kind_of?(NSData)
53
+ self.create_by_image_data(source, metadata, block)
54
+ elsif source.kind_of?(NSURL)
55
+ self.create_by_video_path(source, block)
56
+ else
57
+ self.create_by_cg_image(source, metadata, block)
58
+ end
59
+ end
60
+
61
+ # Find an asset by a specified asset_url.
62
+ #
63
+ # @param asset_url [NSURL]
64
+ # @return [nil]
65
+ #
66
+ # @yield [asset, error]
67
+ # @yieldparam asset [MotionAL::Asset] A found asset.
68
+ # @yieldparam error [error]
69
+ #
70
+ # @example
71
+ # MotionAL::Asset.find_by_url(url) do |asset, error|
72
+ # # asynchronous if a block given
73
+ # p asset.url.absoluteString
74
+ # end
75
+ def self.find_by_url(asset_url, &block)
76
+ url = asset_url.is_a?(String) ? NSURL.alloc.initWithString(asset_url) : asset_url
77
+ self.origin_find_by_url(url, block)
78
+ end
79
+
80
+ # Find and enumerate assets by options.
81
+ #
82
+ # @param options [Hash]
83
+ # @option options [MotionAL::Group] :group Default is the Camera Roll.
84
+ # @option options [Symbol] :filter :all, :photo or :video
85
+ # @option options [Symbol] :order :asc or :desc
86
+ # @option options [NSIndexSet] :indexset
87
+ # @return [nil]
88
+ #
89
+ # @yield [asset, error]
90
+ # @yieldparam asset [MotionAL::Asset] A found asset.
91
+ # @yieldparam error [error]
92
+ #
93
+ # @example
94
+ # MotionAL::Asset.find_all do |asset, error|
95
+ # # asynchronous if a block given
96
+ # p asset.url.absoluteString
97
+ # end
98
+ #
99
+ # MotionAL::find_by_name('MyAppAlbum') do |group|
100
+ # MotionAL::Asset.find_all(group: group, order: :desc, filter: :photo) do |asset|
101
+ # p asset.url.absoluteString
102
+ # end
103
+ # end
104
+ #
105
+ # indexset = NSMutableIndexSet.indexSetWithIndexesInRange(1..3)
106
+ # MotionAL::Asset.find_all(indexset: indexset, order: :desc) do |asset|
107
+ # p asset.url.absoluteString
108
+ # end
109
+ def self.find_all(options = {}, &block)
110
+ self.origin_find_all(options, block)
111
+ end
112
+ class << self
113
+ alias_method :each, :find_all
114
+ end
115
+
116
+ # @return [Boolean] false means ALAssetLibrary cannot treat the video file.
117
+ def self.video_compatible?(video_path_url)
118
+ MotionAL.library.al_asset_library.videoAtPathIsCompatibleWithSavedPhotosAlbum(video_path_url)
119
+ end
120
+
121
+
122
+ # @return [CGImageRef] Returns a thumbnail of the asset.
123
+ def thumbnail
124
+ self.al_asset.thumbnail
125
+ end
126
+
127
+ # @return [CGImageRef] Returns an aspect ratio thumbnail of the asset.
128
+ def aspect_ratio_thumbnail
129
+ self.al_asset.aspectRatioThumbnail
130
+ end
131
+
132
+ # Return true if the app haves write access for the asset.
133
+ # In other words true means the app can call `#update` for the asset.
134
+ #
135
+ # @return [Boolean]
136
+ def editable?
137
+ @al_asset.editable?
138
+ end
139
+
140
+ # The original version of the asset.
141
+ #
142
+ # @return [MotionAL::Asset]
143
+ # @return [nil] The asset has no original asset.
144
+ #
145
+ # @note The original asset was set when the asset was created by `#save_new`
146
+ def original_asset
147
+ original_al_asset = @al_asset.originalAsset
148
+ Asset.new(original_al_asset) if original_al_asset
149
+ end
150
+
151
+ # @return [MotionAL::Representation] The default representation of the asset. A representation is an actual file.
152
+ def default_representation
153
+ @default_representation ||= Representation.new(@asset, @al_asset.defaultRepresentation)
154
+ end
155
+ alias_method :rep, :default_representation
156
+ alias_method :file, :default_representation
157
+ alias_method :representation, :default_representation
158
+
159
+ # wrapper for valueForProperty
160
+ class << self
161
+ private
162
+ # @!macro [attach] make_wrapper
163
+ # The asset's $1
164
+ # @method $1
165
+ # @return [$3] The value for the property $2.
166
+ # @return [nil] The property is empty.
167
+ def make_wrapper_for_property(method_name, property_name, type_of_return)
168
+ define_method(method_name) do
169
+ @al_asset.valueForProperty(property_name)
170
+ end
171
+ end
172
+ end
173
+ make_wrapper_for_property(:location, ALAssetPropertyLocation, "CLLocation")
174
+ make_wrapper_for_property(:duration, ALAssetPropertyDuration, "Float")
175
+ make_wrapper_for_property(:date, ALAssetPropertyDate, "Time")
176
+ make_wrapper_for_property(:url, ALAssetPropertyAssetURL, "NSURL")
177
+ make_wrapper_for_property(:representation_utis, ALAssetPropertyRepresentations, "Array")
178
+ make_wrapper_for_property(:representation_urls, ALAssetPropertyURLs, "Array")
179
+
180
+ alias_method :reps, :representations
181
+ alias_method :files, :representations
182
+
183
+ # The type of the asset.
184
+ #
185
+ # @return [Symbol] :photo or :video
186
+ def asset_type
187
+ MotionAL.asset_types.key(@al_asset.valueForProperty(ALAssetPropertyType))
188
+ end
189
+
190
+ # The orientation of the asset.
191
+ #
192
+ # @return [Symbol] :up, :down :left, :right, :up_mirrored, :down_mirrored, :left_mirrored or :right_mirrored
193
+ def orientation
194
+ MotionAL.asset_orientations.key(@al_asset.valueForProperty(ALAssetPropertyOrientation))
195
+ end
196
+
197
+ class << self
198
+ private
199
+ # wrapper for representation method
200
+ # @!macro [attach] make_wrapper
201
+ # The default representation's $1
202
+ # @method $1
203
+ # @return [$2] The same as the default representation's $1
204
+ # @return [nil] The property is empty.
205
+ def make_wrapper_for_representation_method(method_name, type_of_return)
206
+ define_method(method_name) do
207
+ default_representation.send(method_name)
208
+ end
209
+ end
210
+ end
211
+ make_wrapper_for_representation_method(:full_resolution_image, "CGImageRef")
212
+ make_wrapper_for_representation_method(:full_screen_image, "CGImageRef")
213
+ make_wrapper_for_representation_method(:scale, "Float")
214
+ make_wrapper_for_representation_method(:data, "NSConcreteData")
215
+ make_wrapper_for_representation_method(:cg_image, "CGImageRef")
216
+ make_wrapper_for_representation_method(:dimensions, "CGSize")
217
+ make_wrapper_for_representation_method(:filename, "String")
218
+ make_wrapper_for_representation_method(:size, "Fixnum")
219
+ make_wrapper_for_representation_method(:metadata, "Hash")
220
+
221
+ # Create a new asset forked by the asset.
222
+ #
223
+ # @param source [NSData, NSURL] NSData for the photo, NSURL for the video.
224
+ # @param metadata [Hash] Metadata for the photo.
225
+ # @return [nil]
226
+ #
227
+ # @yield [asset, error]
228
+ # @yieldparam asset [MotionAL::Asset] A created asset.
229
+ # @yieldparam error [error]
230
+ #
231
+ # @note use `MotionAL::Asset.video_compatible?(video_path_url)` before creating video.
232
+ #
233
+ # @example
234
+ # asset_a.save_new(imagedata, meta) do |asset, error| do
235
+ # # asynchronous if a block given
236
+ # p asset.url.absoluteString
237
+ # p asset.original_asset.url.absoluteString
238
+ # end
239
+ #
240
+ # asset_a.create(imagedata, meta)
241
+ def save_new(source, metadata = nil, &block)
242
+ origin_save_new(source, metadata, block)
243
+ end
244
+
245
+ # Update the asset.
246
+ # In other words replacing the asset's representation.
247
+ #
248
+ # @param source [NSData, NSURL] NSData for the photo, NSURL for the video.
249
+ # @param metadata [Hash] Metadata for the photo.
250
+ # @return [nil]
251
+ #
252
+ # @yield [asset, error]
253
+ # @yieldparam asset [MotionAL::Asset] A updated asset.
254
+ # @yieldparam error [error]
255
+ #
256
+ # @note use `MotionAL::Asset.video_compatible?(video_path_url)` before updating video.
257
+ #
258
+ # @example
259
+ # asset_a.update(imagedata, meta) do |asset, error| do
260
+ # # asynchronous if a block given
261
+ # p asset.url.absoluteString
262
+ # end
263
+ #
264
+ # asset_a.update(imagedata, meta)
265
+ def update(source, metadata = nil, &block)
266
+ origin_update(source, metadata, block)
267
+ end
268
+
269
+ private
270
+ def self.create_by_cg_image(cg_image, meta, callback = nil)
271
+ if self.only_orientation?(meta)
272
+ MotionAL.library.al_asset_library.writeImageToSavedPhotosAlbum(
273
+ cg_image,
274
+ orientation: MotionAL.asset_orientations[meta[:orientation]],
275
+ completionBlock: self.completion_block_for_create(callback)
276
+ )
277
+ else
278
+ MotionAL.library.al_asset_library.writeImageToSavedPhotosAlbum(
279
+ cg_image,
280
+ metadata: meta,
281
+ completionBlock: self.completion_block_for_create(callback)
282
+ )
283
+ end
284
+ end
285
+
286
+ def self.only_orientation?(meta)
287
+ meta && meta.size == 1 && meta[:orientation]
288
+ end
289
+
290
+ def self.origin_find_by_url(asset_url, callback = nil)
291
+
292
+ MotionAL.library.al_asset_library.assetForURL(
293
+ asset_url,
294
+ resultBlock: lambda {|al_asset|
295
+ if al_asset
296
+ found_asset = self.new(al_asset)
297
+ callback.call(found_asset, nil) if callback
298
+ end
299
+ },
300
+ failureBlock: lambda {|error|
301
+ callback.call(nil, error) if callback
302
+ }
303
+ )
304
+ end
305
+
306
+ def self.origin_find_all(options = {}, callback = nil)
307
+ if options[:group]
308
+ group_name = options[:group].name
309
+ else
310
+ group_name = /Camera Roll|Saved Photos/
311
+ end
312
+ options[:order] ||= :asc
313
+
314
+ MotionAL::Group.find_by_name(group_name) do |group, error|
315
+ order = MotionAL.enum_orders[options[:order]]
316
+ AssetsFilter.set(group, options[:filter]) if options[:filter]
317
+ if options[:indexset]
318
+ group.al_asset_group.enumerateAssetsAtIndexes(
319
+ options[:indexset],
320
+ options: order,
321
+ usingBlock: using_block_for_all(options, callback)
322
+ )
323
+ elsif options[:order] == :desc
324
+ group.al_asset_group.enumerateAssetsWithOptions(order, usingBlock: using_block_for_all(options, callback))
325
+ else
326
+ group.al_asset_group.enumerateAssetsUsingBlock(using_block_for_all(options, callback))
327
+ end
328
+ AssetsFilter.reset(group) if options[:filter]
329
+ end
330
+ end
331
+
332
+ def self.using_block_for_all(options, callback = nil)
333
+ Proc.new do |al_asset, index, stop|
334
+ if !al_asset.nil?
335
+ asset = Asset.new(al_asset)
336
+ callback.call(asset, nil) if callback
337
+ end
338
+ end
339
+ end
340
+
341
+ def self.create_by_image_data(image_data, meta, callback = nil)
342
+ MotionAL.library.al_asset_library.writeImageDataToSavedPhotosAlbum(
343
+ image_data,
344
+ metadata: meta,
345
+ completionBlock: self.completion_block_for_create(callback)
346
+ )
347
+ end
348
+
349
+ def self.create_by_video_path(video_path_url, callback = nil)
350
+ MotionAL.library.al_asset_library.writeVideoAtPathToSavedPhotosAlbum(
351
+ video_path_url,
352
+ completionBlock: self.completion_block_for_create(callback)
353
+ )
354
+ end
355
+
356
+ def self.completion_block_for_create(callback = nil)
357
+ Proc.new do |asset_url, error|
358
+ MotionAL::Asset.find_by_url(asset_url) do |asset, error|
359
+ callback.call(asset, error) if callback
360
+ end
361
+ end
362
+ end
363
+
364
+ def completion_block_for_save_and_update(callback = nil)
365
+ Proc.new do |asset_url, error|
366
+ MotionAL::Asset.find_by_url(asset_url) do |asset, error|
367
+ @created_asset = asset
368
+ callback.call(@created_asset, error) if callback
369
+ end
370
+ end
371
+ end
372
+
373
+ def origin_save_new(source, metadata, callback = nil)
374
+ case self.asset_type
375
+ when :photo
376
+ save_new_by_image_data(source, metadata) {|asset, error| callback.call(asset, error) if callback }
377
+ when :video
378
+ save_new_by_video_path(source) {|asset, error| callback.call(asset, error) if callback }
379
+ else
380
+ raise "ALAssetTypeUnknown"
381
+ end
382
+ end
383
+
384
+ def save_new_by_image_data(image_data, metadata, &block)
385
+ @al_asset.writeModifiedImageDataToSavedPhotosAlbum(
386
+ image_data,
387
+ metadata: metadata,
388
+ completionBlock: completion_block_for_save_and_update(block)
389
+ )
390
+ end
391
+
392
+ def save_new_by_video_path(video_path, &block)
393
+ @al_asset.writeModifiedVideoAtPathToSavedPhotosAlbum(
394
+ video_path,
395
+ completionBlock: completion_block_for_save_and_update(block)
396
+ )
397
+ end
398
+
399
+ def origin_update(source, metadata = nil, callback = nil)
400
+ case self.asset_type
401
+ when :photo
402
+ update_by_image_data(source, metadata) {|asset, error| callback.call(asset, error) if callback }
403
+ when :video
404
+ update_by_video_path(source) {|asset, error| callback.call(asset, error) if callback}
405
+ else
406
+ raise "ALAssetTypeUnknown"
407
+ end
408
+ end
409
+
410
+ def update_by_image_data(image_data, metadata, &block)
411
+ @al_asset.setImageData(
412
+ image_data,
413
+ metadata: metadata,
414
+ completionBlock: completion_block_for_save_and_update(block)
415
+ )
416
+ end
417
+
418
+ def update_by_video_path(video_path, &block)
419
+ @al_asset.setVideoAtPath(
420
+ video_path,
421
+ completionBlock: completion_block_for_save_and_update(block)
422
+ )
423
+ end
424
+
425
+ end
426
+ end