PackingPeanut 0.0.3 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12a47cd8b03f2575cbec3c3768afd5827e3459f7
4
- data.tar.gz: 07bdafd4af83852cd593c96af077634284d3370f
3
+ metadata.gz: e2f04de5df63f75fb232e267e56ce3f33bc0eefb
4
+ data.tar.gz: 9ad3ba2c1db95ad649252daa5a85c7c786d12419
5
5
  SHA512:
6
- metadata.gz: 2298a6a63b15c41318495495b3c9b64b30fe3f80c6f96673e92ba7df7f0c10331441b1ad4e99b217b2272123efe9995e83c68decc9161473f134ff0e07ca03ae
7
- data.tar.gz: 44023b702723b79591bb23bad85b1c4d2f18c330515a382cdcada4bde59c8ae5ffc02aa17ca91faf8303f6369fbcdba451fad2bf476ad19a14b8603331acdcc9
6
+ metadata.gz: 6fc18eab2b1d752c17d3c8f78df711e4f53fe66ecdf8bb94940b457c8d8be0adbfe857eda9822b69b526857cc3d90c9b21f831e57bb46ea312b4a14b8812c001
7
+ data.tar.gz: b752f132729c59c907d92b1f075bcff4aee493cfe8a35b519303c3a59c190612f2cfc3650204602209d777faec73722f181c04cb29c567e8e9129468d23c76a3
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # ![PackingPeanut Logo](./_art/logo_100.png) PackingPeanut [![Gem Version](https://badge.fury.io/rb/PackingPeanut.svg)](http://badge.fury.io/rb/PackingPeanut)
2
2
 
3
- iOS has [BubbleWrap](https://github.com/rubymotion/BubbleWrap) for App Persistence : Android has PackingPeanut
3
+ ### Cross Platform App Persistence
4
+ ![cross platform rubymotion gem](./_art/both_icon.png)
4
5
 
5
- There is a sedulous effort to make this syntax fit BubbleWrap's as much as possible, but differences simply exist, either for good, technical, or sometimes diabolical reasons :smiling_imp:
6
+ Inspired by BubbleWrap's easy syntax for App Persistence - Now a CROSS PLATFORM App Persistence Gem for RubyMotion.
7
+
8
+ There is a sedulous effort to make this syntax fit BubbleWrap's as much as possible for easy replacement :smiling_imp:
6
9
 
7
10
  [**GITHUB HOMEPAGE**](http://gantman.github.io/PackingPeanut/)
8
11
 
@@ -16,6 +19,10 @@ There is a sedulous effort to make this syntax fit BubbleWrap's as much as possi
16
19
 
17
20
  $ bundle
18
21
 
22
+ **Step 3:** IF on Android:
23
+
24
+ $ [bundle exec] rake gradle:install
25
+
19
26
  ## Usage
20
27
 
21
28
  **It's as simple as:**
@@ -26,32 +33,34 @@ App::Persistence[:foo] = true
26
33
 
27
34
  Whirlwind Tour via the REPL
28
35
  ```
29
- # PP automatically has context if the module is included
30
- # In this case we need to set the context
36
+ # ONLY ANDROID REQUIRES CONTEXT!
37
+ # Set the context (required in the REPL or when not including the module).
31
38
  $ App::Persistence.context = self
32
39
  => #<MainActivity:0x1d20058e>
33
40
  $ App::Persistence['dinner'] = "nachos"
34
- => true # This differs from Bubblewrap.... boolean on success for save (more informative)
35
- $ App::Persistence['dinner']
41
+ => "nachos"
42
+ $ App::Persistence['dinner']
36
43
  => "nachos"
37
44
  $ App::Persistence[:lunch] = "tacos"
38
45
  => "tacos" # Use symbols or strings as you please
39
46
  $ App::Persistence.all
40
- => [{:dinner=>"nachos"}, {:lunch=>"tacos"}]
47
+ => {"dinner"=>"nachos", "lunch"=>"tacos"}
41
48
  $ App::Persistence.storage_file = "some_new_file"
42
49
  => "some_new_file"
43
50
  $ App::Persistence['dinner']
44
51
  => "" # empty because we're now outside the default storage file.
45
- $ App::Persistence.preference_mode = :world_readable
46
- => :world_redable
47
- $ PP::Persistence['some_boolean'] = true #You can use PP instead of App if you like
48
- ```
49
52
 
53
+ # You can use PP instead of App::Persistence if you like
54
+ $ PP['some_boolean'] = true
50
55
 
56
+ # On Android you can set prefrence_modes for cross/app communication
57
+ $ App::Persistence.preference_mode = :world_readable
58
+ => :world_readable
59
+ ```
51
60
 
52
61
  ## What are preference modes?
53
62
 
54
- Preference Modes are ANdroid Operating modes. Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions. The bit MODE_MULTI_PROCESS can also be used if multiple processes are mutating the same SharedPreferences file. MODE_MULTI_PROCESS is always on in apps targeting Gingerbread (Android 2.3) and below, and off by default in later versions.
63
+ Preference Modes are Android Operating modes, used to control permission levels on the persistence file.
55
64
 
56
65
  Memorizable symbols and their corresponding constants:
57
66
  ```ruby
@@ -66,11 +75,15 @@ Memorizable symbols and their corresponding constants:
66
75
  }
67
76
  ```
68
77
 
69
- ## Limitations?
70
- Achilles, the Death Star, and video game villians always have a significant catch. As of right now, you can only store **strings, ints, and booleans**. The data is serialized, and should support hashes, arrays, and floats but alas, I claim there be bugs in conversions via RM Android.
78
+ Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE for more permissive modes. The bit MODE_MULTI_PROCESS can also be used if multiple processes are mutating the same SharedPreferences file. MODE_MULTI_PROCESS is always on in apps targeting Gingerbread (Android 2.3) and below, and off by default in later versions.
79
+
80
+ ## Dependencies
81
+ Adding [Darin's moran gem](https://github.com/darinwilson/moran) allowed serialization of hashes for Android. This means `motion-gradle` is also necessary for complete Packing Peanut excellence on Android.
71
82
 
72
83
  ## Tests?
73
- Boy that would be nice wouldn't it?
84
+
85
+ * **iOS:** Yup!
86
+ * **Android:** Boy that would be nice wouldn't it?
74
87
 
75
88
  ## Contributing
76
89
 
@@ -23,27 +23,29 @@ module App
23
23
  # Serialize key/value as json then
24
24
  # store that string with the settings key == json key
25
25
  def []=(key, value)
26
+ # Let's play nice with strings and non-strings
27
+ string_key = key.to_s
26
28
  settings = get_settings
27
29
  editor = settings.edit
28
- json = serialize(key,value)
29
- editor.putString(key, json.toString)
30
- editor.commit
30
+ json = serialize(string_key,value)
31
+ editor.putString(string_key, json.toString)
32
+ editor.commit
31
33
  end
32
34
 
33
35
  def [](key)
34
- json_string = get_value(key)
36
+ # Let's play nice with strings and non-strings
37
+ string_key = key.to_s
38
+ json_string = get_value(string_key)
35
39
  return json_string if json_string == ""
36
- deserialize(key, json_string)
40
+ deserialize(string_key, json_string)
37
41
  end
38
42
 
39
43
  def serialize(key, value)
40
- json = JSONObject.new
41
- json.put(key, value)
44
+ Moran.generate({:"#{key}" => value})
42
45
  end
43
46
 
44
47
  def deserialize(key, json_string)
45
- json = JSONObject.new(json_string)
46
- json.get(key)
48
+ Moran.parse(json_string)[key]
47
49
  end
48
50
 
49
51
  def get_value key
@@ -69,7 +71,15 @@ module App
69
71
 
70
72
  def all
71
73
  settings = get_settings
72
- settings.getAll.map { |key, value| {key.to_sym => JSONObject.new(value).get(key)} }
74
+ all_hashes = settings.getAll.map { |key, value| Moran.parse(value) }
75
+
76
+ # Currently an array of hashes, needs to be one big hash
77
+ merged_hashes = {}
78
+ all_hashes.each do |h|
79
+ merged_hashes = merged_hashes.merge(h)
80
+ end
81
+
82
+ merged_hashes
73
83
  end
74
84
 
75
85
  def get_settings
@@ -79,15 +89,17 @@ module App
79
89
  # Allows us to use this from anywhere by setting the context
80
90
  # Useful when you want to access this module from the REPL
81
91
  def current_context
92
+ #p defined? getApplicationContext
82
93
  @context || getApplicationContext
83
94
  end
84
95
 
85
96
  # attr_accessor is not supported for modules in RMAndroid... yet.
86
- def context= supplied_context
97
+ def context= supplied_context
87
98
  @context = supplied_context
88
99
  end
89
100
 
90
101
  end
91
102
  end
92
103
 
93
- PP = App
104
+ # delicious shortcut
105
+ PP = App::Persistence unless defined? PP
@@ -0,0 +1,68 @@
1
+ # Persistence module built on top of NSUserDefaults
2
+ module App
3
+ module Persistence
4
+ module_function
5
+
6
+ def app_key
7
+ @app_key ||= NSBundle.mainBundle.bundleIdentifier
8
+ end
9
+
10
+ def storage_file
11
+ @persistence_storage_file ||= "default_persistence_file"
12
+ end
13
+
14
+ def storage_file=(value)
15
+ @persistence_storage_file = value
16
+ end
17
+
18
+ def []=(key, value)
19
+ storage.setObject(value, forKey: storage_key(key))
20
+ storage.synchronize
21
+ end
22
+
23
+ def [](key)
24
+ value = storage.objectForKey storage_key(key)
25
+
26
+ # RubyMotion currently has a bug where the strings returned from
27
+ # standardUserDefaults are missing some methods (e.g. to_data).
28
+ # And because the returned object is slightly different than a normal
29
+ # String, we can't just use `value.is_a?(String)`
30
+ value.class.to_s == 'String' ? value.dup : value
31
+ end
32
+
33
+ def merge(values)
34
+ values.each do |key, value|
35
+ storage.setObject(value, forKey: storage_key(key))
36
+ end
37
+ storage.synchronize
38
+ end
39
+
40
+ def delete(key)
41
+ value = storage.objectForKey storage_key(key)
42
+ storage.removeObjectForKey(storage_key(key))
43
+ storage.synchronize
44
+ value
45
+ end
46
+
47
+ def storage
48
+ NSUserDefaults.standardUserDefaults
49
+ end
50
+
51
+ def storage_key(key)
52
+ "#{app_key}_#{storage_file}_#{key}"
53
+ end
54
+
55
+ def all
56
+ hash = storage.dictionaryRepresentation.select{|k,v| k.start_with?("#{app_key}_#{storage_file}") }
57
+ new_hash = {}
58
+ hash.each do |k,v|
59
+ new_hash[k.sub("#{app_key}_#{storage_file}_", '')] = v
60
+ end
61
+ new_hash
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ # delicious shortcut
68
+ PP = App::Persistence unless defined? PP
@@ -0,0 +1,15 @@
1
+ # Reopens the NSUserDefaults class to add Array like accessors
2
+ # @see https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/nsuserdefaults_Class/Reference/Reference.html
3
+ class NSUserDefaults
4
+
5
+ # Retrieves the object for the passed key
6
+ def [](key)
7
+ self.objectForKey(key.to_s)
8
+ end
9
+
10
+ # Sets the value for a given key and save it right away.
11
+ def []=(key, val)
12
+ self.setObject(val, forKey: key.to_s)
13
+ self.synchronize
14
+ end
15
+ end
@@ -1,12 +1,32 @@
1
1
  # encoding: utf-8
2
-
3
2
  unless defined?(Motion::Project::Config)
4
- raise "This file must be required within a RubyMotion project Rakefile."
3
+ raise "The PackingPeanut gem must be required within a RubyMotion project Rakefile."
4
+ end
5
+
6
+ # WHAT ARE WE?
7
+ platform = Motion::Project::App.respond_to?(:template) ? Motion::Project::App.template : :ios
8
+ if platform.to_s.start_with?('ios')
9
+ platform_name = 'ios'
10
+ elsif platform.to_s.start_with?('android')
11
+ platform_name = 'android'
5
12
  end
6
13
 
7
- lib_dir_path = File.dirname(File.expand_path(__FILE__))
14
+ # necessary for Android gem dependency as of 5/9/2015
15
+ require "moran" if platform_name == "android"
16
+
8
17
  Motion::Project::App.setup do |app|
9
- app.files.unshift(Dir.glob(File.join(lib_dir_path, "project/**/*.rb")))
10
- # Required for android as off 4/11/2015
11
- app.files.flatten!
18
+ platform_lib = File.join(File.dirname(__FILE__), "PackingPeanut-#{platform_name}")
19
+ unless File.exists? platform_lib
20
+ raise "Sorry, the platform #{platform.inspect} (aka #{platform_name}) is not supported by PackingPeanut"
21
+ end
22
+
23
+ # scans app.files until it finds app/ (the default)
24
+ # if found, it inserts just before those files, otherwise it will insert to
25
+ # the end of the list
26
+ insert_point = app.files.find_index { |file| file =~ /^(?:\.\/)?app\// } || 0
27
+
28
+ Dir.glob(File.join(platform_lib, '**/*.rb')).reverse.each do |file|
29
+ app.files.insert(insert_point, file)
30
+ end
31
+
12
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: PackingPeanut
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gant
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-13 00:00:00.000000000 Z
11
+ date: 2015-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -24,7 +24,35 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- description: App persistent data for RubyMotion Android
27
+ - !ruby/object:Gem::Dependency
28
+ name: moran
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: motion-gradle
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: App persistent data for RubyMotion Android and iOS
28
56
  email:
29
57
  - GantMan@gmail.com
30
58
  executables: []
@@ -32,8 +60,10 @@ extensions: []
32
60
  extra_rdoc_files: []
33
61
  files:
34
62
  - README.md
63
+ - lib/PackingPeanut-android/PackingPeanut.rb
64
+ - lib/PackingPeanut-ios/PackingPeanut.rb
65
+ - lib/PackingPeanut-ios/ns_user_defaults.rb
35
66
  - lib/PackingPeanut.rb
36
- - lib/project/PackingPeanut.rb
37
67
  homepage: http://gantman.github.io/PackingPeanut/
38
68
  licenses:
39
69
  - MIT
@@ -57,6 +87,6 @@ rubyforge_project:
57
87
  rubygems_version: 2.4.5
58
88
  signing_key:
59
89
  specification_version: 4
60
- summary: App persistent data for RubyMotion Android, designed to fit the API stylings
61
- of the popular iOS Gem BubbleWrap which also supplies persistence.
90
+ summary: App persistent data for RubyMotion Android and iOS, designed to fit the API
91
+ stylings of the popular iOS Gem BubbleWrap which also supplies persistence.
62
92
  test_files: []