motion-settings 0.0.1
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 +18 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +142 -0
- data/Rakefile +2 -0
- data/lib/motion-settings.rb +8 -0
- data/lib/motion-settings/rmsettable.rb +97 -0
- data/lib/motion-settings/rmsettings.rb +182 -0
- data/lib/motion-settings/version.rb +5 -0
- data/motion-settings.gemspec +17 -0
- metadata +56 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jonathan Silverman
|
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,142 @@
|
|
1
|
+
RubyMotion-UserSettings
|
2
|
+
===================
|
3
|
+
|
4
|
+
An extension to allow RubyMotion apps easy access to reading, writing, and persisting user settings and other objects on iOS via NSUserDefaults.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
Copy the `rmsettable.rb` and `rmsettings.rb` into your `/app` directory. As there isn't yet a convention for where to put these sorts of files, I'd recommend adding a `/app/lib/rm_settings` directory.
|
10
|
+
|
11
|
+
/project
|
12
|
+
/app
|
13
|
+
/lib
|
14
|
+
/rm_settings
|
15
|
+
rmsettable.rb
|
16
|
+
rmsettings.rb
|
17
|
+
|
18
|
+
Setup
|
19
|
+
-----
|
20
|
+
|
21
|
+
Given the way RubyMotion compiles files, you will probably need to add the RMSettings files to your `Rakefile` files_dependencies options.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
Motion::Project::App.setup do |app|
|
25
|
+
app.files_dependencies 'app/app_delegate.rb' => 'app/lib/rm_settings/rmsettable.rb',
|
26
|
+
'app/lib/rm_settings/rmsettable.rb' => 'app/lib/rm_settings/rmsettings.rb'
|
27
|
+
|
28
|
+
...
|
29
|
+
```
|
30
|
+
|
31
|
+
Usage
|
32
|
+
-----
|
33
|
+
|
34
|
+
### Initializing
|
35
|
+
|
36
|
+
To begin, include `RMSettable` inside the `AppDelegate` class of `/app/app_delegate.rb` and call the `rm_settable` function with your other `didFinishLaunchingWithOptions` code.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
class AppDelegate
|
40
|
+
include RMSettable
|
41
|
+
|
42
|
+
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
43
|
+
rm_settable :name, :background_color
|
44
|
+
|
45
|
+
...
|
46
|
+
```
|
47
|
+
|
48
|
+
In its simplest form, the `rm_settable` function is called with a list of symbols for the settings your app will save to the NSUserDefaults.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
rm_settable :name, :background_color
|
52
|
+
```
|
53
|
+
|
54
|
+
By default, the settings are stored as objects. If you wish to cast as a specific type, you may declare that as a hash on the key.
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
rm_settable :name, age: {type: :integer}, completed_tutorial: {type: :boolean}
|
58
|
+
```
|
59
|
+
|
60
|
+
The types available derive from the NSUserDefault class. They can be :array, :boolean, :data, :dictionary, :double, :float, :integer, :object, :string_array, :string, or :url.
|
61
|
+
|
62
|
+
### Options
|
63
|
+
|
64
|
+
Additionally, you can include a hash of options to affect the way RMSettings works.
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
rm_settable age:, name: {type: :string}, options: {autosave: false, default_type: :integer}
|
68
|
+
```
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
rm_settable options: {lenient_keys: true}
|
72
|
+
```
|
73
|
+
|
74
|
+
#### Available Options
|
75
|
+
* `autosave` _(true)_
|
76
|
+
|
77
|
+
By default, settings are synchronized to the device as soon as
|
78
|
+
it is updated. However, if you are updating a lot of items at once
|
79
|
+
or would prefer to manually call save on the settings object, set
|
80
|
+
this to false. Be aware that iOS will still save the settings
|
81
|
+
periodically without being explicitly called.
|
82
|
+
|
83
|
+
Regardless of this setting, settings will also be saved when
|
84
|
+
`applicationDidEnterBackground` or `applicationWillTerminate` is called
|
85
|
+
on the app. To prevent this behaviour, you must override these methods
|
86
|
+
in your `app_delegate.rb`.
|
87
|
+
|
88
|
+
* `default_type` _(:object)_
|
89
|
+
|
90
|
+
Items are saved as objects. You many also specify a particular
|
91
|
+
type when you declare the setting names. With this setting you
|
92
|
+
may override the default type for all settings.
|
93
|
+
|
94
|
+
* `lenient_keys` _(false)_
|
95
|
+
|
96
|
+
If you don't want to declare any or all of the settings you will
|
97
|
+
be storing, set this to true. Any setting not explicitly declared
|
98
|
+
will still be stored and retrieved as the default setting type.
|
99
|
+
|
100
|
+
### Reading and Writing User Settings
|
101
|
+
|
102
|
+
A method named `settings` is added to the application's delegate and supplies a simple interface to the user settings.
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
# write a setting
|
106
|
+
UIApplication.sharedApplication.delegate.settings.name = 'Karl Pilkington'
|
107
|
+
UIApplication.sharedApplication.delegate.settings[:head_shape] = 'Orange'
|
108
|
+
|
109
|
+
# read a setting
|
110
|
+
@name = UIApplication.sharedApplication.delegate.settings.name
|
111
|
+
@head_shape = UIApplication.sharedApplication.delegate.settings[:head_shape]
|
112
|
+
|
113
|
+
# check a setting's boolean value or blankness
|
114
|
+
UIApplication.sharedApplication.delegate.settings.name?
|
115
|
+
|
116
|
+
# reset a setting to its default (also aliased as 'reset' or 'remove')
|
117
|
+
UIApplication.sharedApplication.delegate.settings.delete :name
|
118
|
+
```
|
119
|
+
|
120
|
+
Extras
|
121
|
+
------
|
122
|
+
|
123
|
+
Convenience subclasses are provided for `UIViewController` and `UIView` called `RMViewController` and `RMView`. If you derive your views and controllers form these classes you will have even easier access to the application's settings.
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
class MyCoolView < RMView
|
127
|
+
|
128
|
+
def headClassifier
|
129
|
+
if !settings.head_shape? and settings.username =~ /karl\spilkington/i
|
130
|
+
settings.head_shape = 'Orange'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
...
|
134
|
+
```
|
135
|
+
|
136
|
+
To Do
|
137
|
+
-----
|
138
|
+
* Add tests
|
139
|
+
* Add error reporting
|
140
|
+
* Check that passed data types are valid
|
141
|
+
* Add support for setting default value at declaration
|
142
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require "motion-settings/version"
|
2
|
+
|
3
|
+
Motion::Project::App.setup do |app|
|
4
|
+
app.development do
|
5
|
+
app.files << File.expand_path(File.dirname(__FILE__) + '/motion-settings/rmsettable.rb')
|
6
|
+
app.files << File.expand_path(File.dirname(__FILE__) + '/motion-settings/rmsettings.rb')
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# rmsettable.rb
|
2
|
+
# https://github.com/AaronH/RubyMotion-UserSettings
|
3
|
+
|
4
|
+
module RMSettable
|
5
|
+
|
6
|
+
def rm_settable(*args)
|
7
|
+
# Call this in your app_delegate.rb as part of the didFinishLaunchingWithOptions setup.
|
8
|
+
#
|
9
|
+
# The arguments can consist of symbols for various settings you wish to store.
|
10
|
+
#
|
11
|
+
# rm_settable :name, :background_color
|
12
|
+
#
|
13
|
+
#
|
14
|
+
# By default, the keys store and retrieve generic objects. If you wish to specify a
|
15
|
+
# particular type, you may declare that as a hash on the key.
|
16
|
+
#
|
17
|
+
# rm_settable :name, age: {type: :integer}, superstar: {type: :boolean}
|
18
|
+
#
|
19
|
+
# AVAILABLE TYPES :array, :boolean, :data, :dictionary, :double, :float,
|
20
|
+
# :integer, :object, :string_array, :string, :url
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# You can also include a hash of options.
|
24
|
+
#
|
25
|
+
# rm_settable name: {type: :string}, age: options: {autosave: false, default_type: :integer}
|
26
|
+
#
|
27
|
+
# rm_settable options: {:lenient_keys}
|
28
|
+
#
|
29
|
+
# AVAILBLE OPTIONS
|
30
|
+
# :autosave true (default)
|
31
|
+
# By default, settings are synchronized to the device as soon as
|
32
|
+
# it is updated. However, if you are updating a lot of items at once
|
33
|
+
# or would prefer to manually call save on the settings object, set
|
34
|
+
# this to false. Be aware that iOS will still save the settings
|
35
|
+
# periodically without being explicitly called.
|
36
|
+
#
|
37
|
+
# :default_type :object (default)
|
38
|
+
# Items are saved as objects. You many specify the type
|
39
|
+
# when you declare the setting names or override the default
|
40
|
+
# expected for all item.
|
41
|
+
#
|
42
|
+
# :lenient_keys false (default)
|
43
|
+
# If you don't want to declare any or all of the settings you will
|
44
|
+
# be storing, set this to true. Any setting not explicitly declared
|
45
|
+
# will be stored and retrieved as the default setting type.
|
46
|
+
#
|
47
|
+
@rm_settings = RMSettings.new args
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def applicationDidEnterBackground(application)
|
52
|
+
# make sure we save any unsaved settings when going to the background
|
53
|
+
# if you override this method in the app_delegate
|
54
|
+
# be sure to call super to save any unsaved settings
|
55
|
+
rm_settings.save
|
56
|
+
end
|
57
|
+
|
58
|
+
def applicationWillTerminate(application)
|
59
|
+
# make sure we save any unsaved settings when being terminated
|
60
|
+
# if you override this method in the app_delegate
|
61
|
+
# be sure to call super to save any unsaved settings
|
62
|
+
rm_settings.save
|
63
|
+
end
|
64
|
+
|
65
|
+
def settings
|
66
|
+
# provide access to the RMSettings object to the app_delegate
|
67
|
+
rm_settings
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.included(base)
|
71
|
+
base.class_eval do
|
72
|
+
attr_accessor :rm_settings
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# These subclasses provide easy access to the app_delegate and settings object.
|
78
|
+
# If you wish to call settings directly from your controller or view, be sure
|
79
|
+
# to inherit from these classes
|
80
|
+
class RMView < UIView
|
81
|
+
def settings
|
82
|
+
application.settings
|
83
|
+
end
|
84
|
+
|
85
|
+
def application
|
86
|
+
UIApplication.sharedApplication.delegate
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class RMViewController < UIViewController
|
91
|
+
def settings
|
92
|
+
application.settings
|
93
|
+
end
|
94
|
+
def application
|
95
|
+
UIApplication.sharedApplication.delegate
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# rmsettings.rb
|
2
|
+
# https://github.com/AaronH/RubyMotion-UserSettings
|
3
|
+
|
4
|
+
class RMSettings
|
5
|
+
attr_accessor :settings, :available, :keys, :options
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
# Initializes the available settings and options
|
9
|
+
# See rmsettable.rb for details on the various options
|
10
|
+
args = args.flatten.compact.uniq
|
11
|
+
@available = {}
|
12
|
+
@settings ||= NSUserDefaults.standardUserDefaults
|
13
|
+
|
14
|
+
user_options = (args.select{|a| a.is_a? Hash}.first || {}).delete(:options) || {}
|
15
|
+
@options = { autosave: true,
|
16
|
+
lenient_keys: false,
|
17
|
+
default_type: :object}.merge(user_options)
|
18
|
+
|
19
|
+
args.flatten.each do |item|
|
20
|
+
if item.is_a?(Symbol)
|
21
|
+
@available[item] = {type: @options[:default_type]}
|
22
|
+
elsif item.is_a?(Hash)
|
23
|
+
item.each do |key, value|
|
24
|
+
@available[key] = value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@keys = @available.keys
|
29
|
+
end
|
30
|
+
|
31
|
+
def save
|
32
|
+
# Save all current settings to the device.
|
33
|
+
# Can be called manually but is generally called automatically
|
34
|
+
# after updating a key unless the :autosave option is false.
|
35
|
+
settings.synchronize
|
36
|
+
end
|
37
|
+
|
38
|
+
def autosave
|
39
|
+
# Automatically saves the data unless autosave is false.
|
40
|
+
save if autosave?
|
41
|
+
end
|
42
|
+
|
43
|
+
def autosave?
|
44
|
+
# Check to see if the autosave option is selected
|
45
|
+
options[:autosave]
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_type_for(key)
|
49
|
+
# Determine the appropriate type for reading and writing item
|
50
|
+
((@available[key] || {})[:type] || @options[:default_type])
|
51
|
+
end
|
52
|
+
|
53
|
+
def setting_for?(key)
|
54
|
+
# Call to check boolean status of a particular key.
|
55
|
+
# Generally called dynamically from the method_missing function.
|
56
|
+
#
|
57
|
+
# settings.setting_for? :tutorial_completed
|
58
|
+
#
|
59
|
+
# settings.tutorial_completed?
|
60
|
+
#
|
61
|
+
value = setting_for(key)
|
62
|
+
case default_type_for(key)
|
63
|
+
when :string, :array
|
64
|
+
value.empty?
|
65
|
+
else
|
66
|
+
!!value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def save_setting(key, value)
|
71
|
+
# Save the contents of value to the key.
|
72
|
+
# Returns the value of the key after setting.
|
73
|
+
#
|
74
|
+
# Generally called dynamically from the method_missing function.
|
75
|
+
#
|
76
|
+
# settings.save_setting :name, 'Karl Pilkington'
|
77
|
+
#
|
78
|
+
# settings.head_shape = 'Orange'
|
79
|
+
#
|
80
|
+
case default_type_for(key)
|
81
|
+
when :boolean
|
82
|
+
settings.setBool value, forKey: key
|
83
|
+
when :double
|
84
|
+
settings.setDouble value, forKey: key
|
85
|
+
when :float
|
86
|
+
settings.setFloat value, forKey: key
|
87
|
+
when :integer
|
88
|
+
settings.setInteger value, forKey: key
|
89
|
+
when :object
|
90
|
+
settings.setObject value, forKey: key
|
91
|
+
when :url
|
92
|
+
settings.setURL value, forKey: key
|
93
|
+
else
|
94
|
+
settings.setObject value, forKey: key
|
95
|
+
end
|
96
|
+
|
97
|
+
autosave
|
98
|
+
|
99
|
+
# return the current value
|
100
|
+
setting_for key
|
101
|
+
end
|
102
|
+
alias :[]= :save_setting
|
103
|
+
|
104
|
+
def setting_for(key)
|
105
|
+
# Read the contents of a given key.
|
106
|
+
#
|
107
|
+
# Generally called dynamically from the method_missing function.
|
108
|
+
#
|
109
|
+
# settings.setting_for :nickname
|
110
|
+
#
|
111
|
+
# settings.nickname
|
112
|
+
#
|
113
|
+
case default_type_for(key)
|
114
|
+
when :array
|
115
|
+
settings.arrayForKey key
|
116
|
+
when :boolean
|
117
|
+
settings.boolForKey key
|
118
|
+
when :data
|
119
|
+
settings.dataForKey key
|
120
|
+
when :dictionary
|
121
|
+
settings.dictionaryForKey key
|
122
|
+
when :double
|
123
|
+
settings.doubleForKey key
|
124
|
+
when :float
|
125
|
+
settings.floatForKey key
|
126
|
+
when :integer
|
127
|
+
settings.integerForKey key
|
128
|
+
when :object
|
129
|
+
settings.objectForKey key
|
130
|
+
when :string_array
|
131
|
+
settings.stringArrayForKey key
|
132
|
+
when :string
|
133
|
+
settings.stringForKey key
|
134
|
+
when :url
|
135
|
+
settings.URLForKey key
|
136
|
+
end
|
137
|
+
end
|
138
|
+
alias :[] :setting_for
|
139
|
+
|
140
|
+
def remove(key)
|
141
|
+
# Resets the key to it's default value and returns that value
|
142
|
+
# Aliased as delete and reset
|
143
|
+
settings.removeObjectForKey key
|
144
|
+
autosave
|
145
|
+
setting_for key
|
146
|
+
end
|
147
|
+
alias :delete :remove
|
148
|
+
alias :reset :remove
|
149
|
+
|
150
|
+
def valid_key?(key)
|
151
|
+
# Checks to see if the method_missing key has been declared
|
152
|
+
# unless that functionality has been turned off in the settings
|
153
|
+
@options[:lenient_keys] or keys.include?(key)
|
154
|
+
end
|
155
|
+
|
156
|
+
def method_missing(method, *args)
|
157
|
+
# Split the method to componenet parts to do our magic.
|
158
|
+
if m = method.to_s.match(/^([^\?\=]+)([\?\=])?$/)
|
159
|
+
base_key = m[1].to_sym
|
160
|
+
method_modifier = m[2]
|
161
|
+
# Check if we want to do something here.
|
162
|
+
if valid_key?(base_key)
|
163
|
+
return case method_modifier
|
164
|
+
when nil
|
165
|
+
# Call the reader
|
166
|
+
setting_for(base_key)
|
167
|
+
when '='
|
168
|
+
# Call the writer
|
169
|
+
save_setting(base_key, [*args].flatten.first)
|
170
|
+
when '?'
|
171
|
+
# Call the boolean check
|
172
|
+
setting_for?(base_key)
|
173
|
+
else
|
174
|
+
# Nothing to do, so let's fail
|
175
|
+
super
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
super
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/motion-settings/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jonathan Silverman"]
|
6
|
+
gem.email = ["jsilver@mdx.la"]
|
7
|
+
gem.description = %q{A convenience wrapper to allow RubyMotion apps easy access to reading, writing, and persisting values via NSUserDefaults.}
|
8
|
+
gem.summary = %q{RubyMotion Settings Library}
|
9
|
+
gem.homepage = "https://github.com/jsilverMDX/RubyMotion-UserSettings"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "motion-settings"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Motion::Settings::VERSION
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: motion-settings
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonathan Silverman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-08 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A convenience wrapper to allow RubyMotion apps easy access to reading,
|
15
|
+
writing, and persisting values via NSUserDefaults.
|
16
|
+
email:
|
17
|
+
- jsilver@mdx.la
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- Gemfile
|
24
|
+
- LICENSE
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- lib/motion-settings.rb
|
28
|
+
- lib/motion-settings/rmsettable.rb
|
29
|
+
- lib/motion-settings/rmsettings.rb
|
30
|
+
- lib/motion-settings/version.rb
|
31
|
+
- motion-settings.gemspec
|
32
|
+
homepage: https://github.com/jsilverMDX/RubyMotion-UserSettings
|
33
|
+
licenses: []
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 1.8.24
|
53
|
+
signing_key:
|
54
|
+
specification_version: 3
|
55
|
+
summary: RubyMotion Settings Library
|
56
|
+
test_files: []
|