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.
- data/.gitignore +20 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/Guardfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +128 -0
- data/Rakefile +15 -0
- data/app/app_delegate.rb +14 -0
- data/lib/motional.rb +11 -0
- data/lib/motional/asset.rb +426 -0
- data/lib/motional/assets.rb +95 -0
- data/lib/motional/assets_filter.rb +33 -0
- data/lib/motional/core.rb +84 -0
- data/lib/motional/group.rb +245 -0
- data/lib/motional/library.rb +32 -0
- data/lib/motional/representation.rb +101 -0
- data/lib/motional/representations.rb +55 -0
- data/lib/motional/version.rb +3 -0
- data/motional.gemspec +24 -0
- data/resources/sample.jpg +0 -0
- data/resources/sample.mp4 +0 -0
- data/spec/motional/asset_spec.rb +274 -0
- data/spec/motional/assets_spec.rb +53 -0
- data/spec/motional/group_spec.rb +137 -0
- data/spec/motional/library_spec.rb +18 -0
- data/spec/motional/representation_spec.rb +57 -0
- data/spec/motional/representations_spec.rb +43 -0
- data/spec/spec_helper.rb +45 -0
- metadata +130 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -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
|
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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
|
data/app/app_delegate.rb
ADDED
@@ -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
|
data/lib/motional.rb
ADDED
@@ -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
|