motion-loco 0.1.0 → 0.1.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.
- checksums.yaml +8 -8
- data/README.md +166 -3
- data/lib/motion-loco/adapter.rb +35 -0
- data/lib/motion-loco/convenience_methods.rb +1 -1
- data/lib/motion-loco/fixture_adapter.rb +71 -0
- data/lib/motion-loco/model.rb +3 -0
- data/lib/motion-loco/observable.rb +15 -9
- data/lib/motion-loco/record_array.rb +29 -0
- data/lib/motion-loco/resizable.rb +3 -1
- data/lib/motion-loco/rest_adapter.rb +128 -0
- data/lib/motion-loco/savable.rb +125 -0
- data/lib/motion-loco/table_view.rb +1 -7
- data/lib/motion-loco/version.rb +1 -1
- data/lib/motion-loco.rb +4 -1
- metadata +41 -8
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZGRkOWJhYjFhZWU5NzE3ODYyYTJlYzIxM2QzODU2NTcwMmY1YzY1Ng==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OTVjMGJkMjcyZDdlYTdjZmM3NzliMDJiMDVlMWVlYTcyY2RlMDA1OA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OWEzMjJlOTk5MTY0OTk1YjZlZTAyNjFjMmU5OGJkMTFhOTI5YTdmYmJkYWNh
|
10
|
+
NWE1MTczMWQ2YWMyOTZlZjA4ZjY1NGRlMWUzMjZkMWFjYmI0NTIyMjcwY2Fi
|
11
|
+
NTgxM2RiYTJmZjM0ZmNjNDEwOTAxY2U0ZjU3ZDZiMGI0NzhlYjQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2MwODBiMjk1MTAwNDMzZjYxZTkwNzE0MDU5NjYzYTJkMDljNTNhNzlkZGUw
|
14
|
+
MmVkZThiZDJkZDIwODUwMDA4YjdjYzY0M2YxZjY3OWVjZWE1NDg2MTc5Yjg4
|
15
|
+
YWViNjJlODgxMmVhYTNhN2Q0ZGM3ODZlYTAxMWM3MGM4MjcyZjk=
|
data/README.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
|
-
# Loco
|
1
|
+
# Motion-Loco
|
2
2
|
|
3
|
-
|
3
|
+
Motion-Loco is a library for [RubyMotion](http://rubymotion.com)
|
4
|
+
that includes [Ember.js](http://emberjs.com) inspired bindings,
|
5
|
+
computed properties, and observers.
|
6
|
+
|
7
|
+
Also included is a set of views that are easier to position and size.
|
8
|
+
|
9
|
+
**I'm not using this in production yet. It might be ready,
|
10
|
+
but I feel like it needs some more features to really be useful.**
|
11
|
+
|
12
|
+
## What's New!
|
13
|
+
|
14
|
+
### June 7th, 2013
|
15
|
+
|
16
|
+
#### Data Adapters
|
17
|
+
|
18
|
+
These are still a bit of a work in progress, but [worth](#locofixtureadapter) [checking out](#locorestadapter)!
|
4
19
|
|
5
20
|
## Installation
|
6
21
|
|
@@ -18,7 +33,155 @@ Or install it yourself as:
|
|
18
33
|
|
19
34
|
## Usage
|
20
35
|
|
21
|
-
|
36
|
+
### Computed Properties
|
37
|
+
|
38
|
+
Computed properties are properties that are computed from one or multiple properties.
|
39
|
+
They beat out using a method because they can be observed like any other property.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
class Person < Loco::Model
|
43
|
+
property :first_name
|
44
|
+
property :last_name
|
45
|
+
|
46
|
+
# Computed property for full name that watches for changes
|
47
|
+
# in the object's first_name and last_name properties.
|
48
|
+
property :full_name, lambda{|object|
|
49
|
+
"#{object.first_name} #{object.last_name}"
|
50
|
+
}.property(:first_name, :last_name)
|
51
|
+
end
|
52
|
+
|
53
|
+
@person = Person.new(
|
54
|
+
first_name: 'Brian',
|
55
|
+
last_name: 'Pattison'
|
56
|
+
)
|
57
|
+
|
58
|
+
@person.full_name # "Brian Pattison"
|
59
|
+
```
|
60
|
+
|
61
|
+
### Bindings
|
62
|
+
|
63
|
+
Bindings are used to link the property of an object to a property of another object.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class Person < Loco::Model
|
67
|
+
property :first_name
|
68
|
+
property :last_name
|
69
|
+
property :full_name, lambda{|object|
|
70
|
+
"#{object.first_name} #{object.last_name}"
|
71
|
+
}.property(:first_name, :last_name)
|
72
|
+
end
|
73
|
+
|
74
|
+
@person = Person.new(
|
75
|
+
first_name: 'Brian',
|
76
|
+
last_name: 'Pattison'
|
77
|
+
)
|
78
|
+
|
79
|
+
@label = Loco::Label.alloc.initWithFrame(
|
80
|
+
textBinding: [@person, 'full_name'],
|
81
|
+
height: 30,
|
82
|
+
top: 20,
|
83
|
+
width: 200
|
84
|
+
)
|
85
|
+
|
86
|
+
@label.text # "Brian Pattison"
|
87
|
+
```
|
88
|
+
|
89
|
+
### Loco::Controller
|
90
|
+
|
91
|
+
A `Loco::Controller` is a singleton class that is especially useful for
|
92
|
+
binding objects' properties to view properties.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
class PersonController < Loco::Controller
|
96
|
+
property :content
|
97
|
+
end
|
98
|
+
|
99
|
+
@label = Loco::Label.alloc.initWithFrame(
|
100
|
+
textBinding: 'PersonController.content.full_name',
|
101
|
+
height: 30,
|
102
|
+
top: 20,
|
103
|
+
width: 200
|
104
|
+
)
|
105
|
+
|
106
|
+
@person = Person.new(
|
107
|
+
first_name: 'Brian',
|
108
|
+
last_name: 'Pattison'
|
109
|
+
)
|
110
|
+
|
111
|
+
PersonController.content = @person
|
112
|
+
|
113
|
+
@label.text # "Brian Pattison"
|
114
|
+
```
|
115
|
+
|
116
|
+
### Loco::TableView
|
117
|
+
|
118
|
+
A `Loco::TableView` is used for to easily bind a collection of objects
|
119
|
+
to a `UITableView` and each item in the collection to a reusable `UITableViewCell`.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
class MyTableViewCell < Loco::TableViewCell
|
123
|
+
# The `view_setup` method is called the first time the cell is created.
|
124
|
+
# Bindings can be made to the item assigned to the cell
|
125
|
+
# by binding to `parentView.content`.
|
126
|
+
def view_setup
|
127
|
+
@label = Loco::Label.alloc.initWithFrame(
|
128
|
+
textBinding: 'parentView.content.first_name',
|
129
|
+
height: 30,
|
130
|
+
left: 60,
|
131
|
+
right: 30,
|
132
|
+
top: 5
|
133
|
+
)
|
134
|
+
self.addSubview(@label)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class MyTableView < Loco::TableView
|
139
|
+
item_view_class MyTableViewCell
|
140
|
+
end
|
141
|
+
|
142
|
+
@table_view = MyTableView.alloc.initWithFrame(
|
143
|
+
content: [Person.new(first_name: 'Brian'), Person.new(first_name: 'Kirsten')],
|
144
|
+
bottom: 0,
|
145
|
+
left: 0,
|
146
|
+
right: 0,
|
147
|
+
top: 0
|
148
|
+
)
|
149
|
+
```
|
150
|
+
|
151
|
+
### Loco::FixtureAdapter
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
class Show < Loco::Model
|
155
|
+
adapter 'Loco::FixtureAdapter'
|
156
|
+
property :title
|
157
|
+
end
|
158
|
+
|
159
|
+
@show = Show.find(2) # Loads from `resources/fixtures/plural_class_name.json`
|
160
|
+
@show.title # "Brian's Video Clip Show"
|
161
|
+
```
|
162
|
+
|
163
|
+
### Loco::RESTAdapter
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
class Post < Loco::Model
|
167
|
+
adapter 'Loco::RESTAdapter', 'http://localhost:3000'
|
168
|
+
property :title
|
169
|
+
property :body
|
170
|
+
end
|
171
|
+
|
172
|
+
@post = Post.new(title: 'New! The Loco::RESTAdapter', body: 'Yay! A REST data adapter!')
|
173
|
+
@post.save do |post|
|
174
|
+
post.id # Yay! It has an ID now!
|
175
|
+
end
|
176
|
+
```
|
177
|
+
|
178
|
+
## Todo
|
179
|
+
|
180
|
+
- State Manager
|
181
|
+
- Relationships
|
182
|
+
- More Adapters
|
183
|
+
- Core Data (Are SQLite and iCloud also part of this adapter??)
|
184
|
+
- Lots of stuff
|
22
185
|
|
23
186
|
## Contributing
|
24
187
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Loco
|
2
|
+
|
3
|
+
class Adapter
|
4
|
+
|
5
|
+
def create_record(record, &block)
|
6
|
+
raise NoMethodError, "Loco::Adapter subclasses must implement #create_record(record, &block)."
|
7
|
+
end
|
8
|
+
|
9
|
+
def find(record, id, &block)
|
10
|
+
raise NoMethodError, "Loco::Adapter subclasses must implement #find(record, id, &block)."
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_all(type, records, &block)
|
14
|
+
raise NoMethodError, "Loco::Adapter subclasses must implement #find_all(type, records, &block)."
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_many(type, records, ids, &block)
|
18
|
+
raise NoMethodError, "Loco::Adapter subclasses must implement #find_many(type, records, ids, &block)."
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_query(type, records, params, &block)
|
22
|
+
raise NoMethodError, "Loco::Adapter subclasses must implement #find_query(type, records, params, &block)."
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_record(record, &block)
|
26
|
+
raise NoMethodError, "Loco::Adapter subclasses must implement #save_record(record, &block)."
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete_record(record, &block)
|
30
|
+
raise NoMethodError, "Loco::Adapter subclasses must implement #delete_record(record, &block)."
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Loco
|
2
|
+
|
3
|
+
class FixtureAdapter < Adapter
|
4
|
+
JSON_OPTIONS = NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves | NSJSONReadingAllowFragments
|
5
|
+
|
6
|
+
class RecordNotFound < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_record(record, &block)
|
10
|
+
raise NoMethodError, "Loco::FixtureAdapter cannot create records."
|
11
|
+
end
|
12
|
+
|
13
|
+
def find(record, id, &block)
|
14
|
+
error = Pointer.new(:id)
|
15
|
+
file = File.read(File.join(NSBundle.mainBundle.resourcePath, "fixtures", "#{record.class.to_s.underscore.pluralize}.json"))
|
16
|
+
data = NSJSONSerialization.JSONObjectWithData(file.to_data, options:JSON_OPTIONS, error:error).find{|obj| obj[:id] == id }
|
17
|
+
if data
|
18
|
+
record.load(id, data)
|
19
|
+
block.call(record) if block.is_a? Proc
|
20
|
+
record
|
21
|
+
else
|
22
|
+
raise Loco::FixtureAdapter::RecordNotFound, "#{record.class} with the id `#{id}' could not be loaded."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_all(type, records, &block)
|
27
|
+
error = Pointer.new(:id)
|
28
|
+
file = File.read(File.join(NSBundle.mainBundle.resourcePath, "fixtures", "#{type.to_s.underscore.pluralize}.json"))
|
29
|
+
data = NSJSONSerialization.JSONObjectWithData(file.to_data, options:JSON_OPTIONS, error:error)
|
30
|
+
records.load(type, data)
|
31
|
+
block.call(records) if block.is_a? Proc
|
32
|
+
records
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_many(type, records, ids, &block)
|
36
|
+
error = Pointer.new(:id)
|
37
|
+
file = File.read(File.join(NSBundle.mainBundle.resourcePath, "fixtures", "#{type.to_s.underscore.pluralize}.json"))
|
38
|
+
data = NSJSONSerialization.JSONObjectWithData(file.to_data, options:JSON_OPTIONS, error:error).select{|obj|
|
39
|
+
ids.map(&:to_s).include?(obj[:id].to_s)
|
40
|
+
}
|
41
|
+
records.load(type, data)
|
42
|
+
block.call(records) if block.is_a? Proc
|
43
|
+
records
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_query(type, records, query, &block)
|
47
|
+
error = Pointer.new(:id)
|
48
|
+
file = File.read(File.join(NSBundle.mainBundle.resourcePath, "fixtures", "#{type.to_s.underscore.pluralize}.json"))
|
49
|
+
data = NSJSONSerialization.JSONObjectWithData(file.to_data, options:JSON_OPTIONS, error:error).select{|obj|
|
50
|
+
match = true
|
51
|
+
query.each do |key, value|
|
52
|
+
match = false if obj[key.to_sym] != value
|
53
|
+
end
|
54
|
+
match
|
55
|
+
}
|
56
|
+
records.load(type, data)
|
57
|
+
block.call(records) if block.is_a? Proc
|
58
|
+
records
|
59
|
+
end
|
60
|
+
|
61
|
+
def save_record(record, &block)
|
62
|
+
raise NoMethodError, "Loco::FixtureAdapter cannot save records."
|
63
|
+
end
|
64
|
+
|
65
|
+
def delete_record(record, &block)
|
66
|
+
raise NoMethodError, "Loco::FixtureAdapter cannot delete records."
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
data/lib/motion-loco/model.rb
CHANGED
@@ -3,9 +3,6 @@ motion_require 'proc'
|
|
3
3
|
module Loco
|
4
4
|
|
5
5
|
module Observable
|
6
|
-
COLLECTION_OPERATIONS = [ NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, NSKeyValueChangeReplacement ]
|
7
|
-
DEFAULT_OPTIONS = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
|
8
|
-
|
9
6
|
# Used to create observable view controllers.
|
10
7
|
def init
|
11
8
|
super
|
@@ -75,7 +72,7 @@ module Loco
|
|
75
72
|
|
76
73
|
def register_observer(target, key_path, &block)
|
77
74
|
unless observer_is_registered?(target, key_path)
|
78
|
-
target.addObserver(self, forKeyPath:key_path.to_s, options:
|
75
|
+
target.addObserver(self, forKeyPath:key_path.to_s, options:0, context:nil)
|
79
76
|
end
|
80
77
|
observers_for(target, key_path) << block
|
81
78
|
end
|
@@ -115,10 +112,8 @@ module Loco
|
|
115
112
|
end
|
116
113
|
|
117
114
|
def observeValueForKeyPath(key_path, ofObject:target, change:change, context:context)
|
118
|
-
|
119
|
-
|
120
|
-
proc.call
|
121
|
-
end
|
115
|
+
observers_for(target, key_path).each do |proc|
|
116
|
+
proc.call
|
122
117
|
end
|
123
118
|
end
|
124
119
|
|
@@ -140,7 +135,10 @@ module Loco
|
|
140
135
|
module ClassMethods
|
141
136
|
def property(name, proc=nil)
|
142
137
|
attr_accessor name
|
143
|
-
|
138
|
+
if proc.nil?
|
139
|
+
@class_properties = get_class_properties
|
140
|
+
@class_properties << name
|
141
|
+
else
|
144
142
|
@class_bindings = get_class_bindings
|
145
143
|
@class_bindings << { name: name, proc: proc }
|
146
144
|
end
|
@@ -157,11 +155,19 @@ module Loco
|
|
157
155
|
@class_bindings ||= []
|
158
156
|
end
|
159
157
|
|
158
|
+
# An array of the model's properties
|
159
|
+
# used for saving the record
|
160
|
+
# @return [Array]
|
161
|
+
def get_class_properties
|
162
|
+
@class_properties ||= []
|
163
|
+
end
|
164
|
+
|
160
165
|
end
|
161
166
|
|
162
167
|
def self.included(base)
|
163
168
|
base.extend(ClassMethods)
|
164
169
|
end
|
170
|
+
|
165
171
|
end
|
166
172
|
|
167
173
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
motion_require 'observable'
|
2
|
+
|
3
|
+
module Loco
|
4
|
+
|
5
|
+
class RecordArray < Array
|
6
|
+
include Observable
|
7
|
+
|
8
|
+
def did_load
|
9
|
+
# Override to perform actions after loading data
|
10
|
+
end
|
11
|
+
alias_method :didLoad, :did_load
|
12
|
+
|
13
|
+
def load(type, data)
|
14
|
+
self.removeAllObjects
|
15
|
+
data.each do |item_data|
|
16
|
+
self.addObject(type.new(item_data))
|
17
|
+
end
|
18
|
+
self.did_load
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(properties={})
|
23
|
+
self.init
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Loco
|
2
|
+
|
3
|
+
class RESTAdapter < Adapter
|
4
|
+
JSON_OPTIONS = NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves | NSJSONReadingAllowFragments
|
5
|
+
|
6
|
+
class RecordNotFound < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
self.url = args.first if args && args.first
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_record(record, &block)
|
15
|
+
BW::HTTP.post("#{self.url}/#{record.class.to_s.underscore.pluralize}.json", { payload: record.serialize(root: true) }) do |response|
|
16
|
+
if response.ok?
|
17
|
+
error = Pointer.new(:id)
|
18
|
+
data = NSJSONSerialization.JSONObjectWithData(response.body, options:JSON_OPTIONS, error:error)
|
19
|
+
record.load(data[record.class.to_s.underscore][:id], data[record.class.to_s.underscore])
|
20
|
+
block.call(record) if block.is_a? Proc
|
21
|
+
else
|
22
|
+
Loco.debug("Responded with #{response.status_code}")
|
23
|
+
Loco.debug(response.error_message)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
record
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete_record(record, &block)
|
30
|
+
BW::HTTP.delete("#{self.url}/#{record.class.to_s.underscore.pluralize}/#{record.id}.json") do |response|
|
31
|
+
if response.ok?
|
32
|
+
block.call(record) if block.is_a? Proc
|
33
|
+
else
|
34
|
+
Loco.debug("Responded with #{response.status_code}")
|
35
|
+
Loco.debug(response.error_message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
record
|
39
|
+
end
|
40
|
+
|
41
|
+
def find(record, id, &block)
|
42
|
+
BW::HTTP.get("#{self.url}/#{record.class.to_s.underscore.pluralize}/#{id}.json") do |response|
|
43
|
+
if response.ok?
|
44
|
+
error = Pointer.new(:id)
|
45
|
+
data = NSJSONSerialization.JSONObjectWithData(response.body, options:JSON_OPTIONS, error:error)
|
46
|
+
record.load(id, data[record.class.to_s.underscore])
|
47
|
+
block.call(record) if block.is_a? Proc
|
48
|
+
else
|
49
|
+
Loco.debug("Responded with #{response.status_code}")
|
50
|
+
Loco.debug(response.error_message)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
record
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_all(type, records, &block)
|
57
|
+
BW::HTTP.get("#{self.url}/#{type.to_s.underscore.pluralize}.json") do |response|
|
58
|
+
if response.ok?
|
59
|
+
error = Pointer.new(:id)
|
60
|
+
data = NSJSONSerialization.JSONObjectWithData(response.body, options:JSON_OPTIONS, error:error)
|
61
|
+
records.load(type, data[type.to_s.underscore.pluralize])
|
62
|
+
block.call(records) if block.is_a? Proc
|
63
|
+
else
|
64
|
+
Loco.debug("Responded with #{response.status_code}")
|
65
|
+
Loco.debug(response.error_message)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
records
|
69
|
+
end
|
70
|
+
|
71
|
+
def find_many(type, records, ids, &block)
|
72
|
+
BW::HTTP.get("#{self.url}/#{type.to_s.underscore.pluralize}.json", { payload: { ids: ids } }) do |response|
|
73
|
+
if response.ok?
|
74
|
+
error = Pointer.new(:id)
|
75
|
+
data = NSJSONSerialization.JSONObjectWithData(response.body, options:JSON_OPTIONS, error:error)
|
76
|
+
records.load(type, data[type.to_s.underscore.pluralize])
|
77
|
+
block.call(records) if block.is_a? Proc
|
78
|
+
else
|
79
|
+
Loco.debug("Responded with #{response.status_code}")
|
80
|
+
Loco.debug(response.error_message)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
records
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_query(type, records, query, &block)
|
87
|
+
BW::HTTP.get("#{self.url}/#{type.to_s.underscore.pluralize}.json", { payload: { query: query } }) do |response|
|
88
|
+
if response.ok?
|
89
|
+
error = Pointer.new(:id)
|
90
|
+
data = NSJSONSerialization.JSONObjectWithData(response.body, options:JSON_OPTIONS, error:error)
|
91
|
+
records.load(type, data[type.to_s.underscore.pluralize])
|
92
|
+
block.call(records) if block.is_a? Proc
|
93
|
+
else
|
94
|
+
Loco.debug("Responded with #{response.status_code}")
|
95
|
+
Loco.debug(response.error_message)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
records
|
99
|
+
end
|
100
|
+
|
101
|
+
def update_record(record, &block)
|
102
|
+
BW::HTTP.put("#{self.url}/#{record.class.to_s.underscore.pluralize}/#{record.id}.json", { payload: record.serialize(root: true) }) do |response|
|
103
|
+
if response.ok?
|
104
|
+
block.call(record) if block.is_a? Proc
|
105
|
+
else
|
106
|
+
Loco.debug("Responded with #{response.status_code}")
|
107
|
+
Loco.debug(response.error_message)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
record
|
111
|
+
end
|
112
|
+
|
113
|
+
def url
|
114
|
+
unless @url.nil?
|
115
|
+
@url
|
116
|
+
else
|
117
|
+
raise ArgumentError, "Loco::RESTAdapter needs a base URL when using in a model. Ex. `adapter 'Loco::RESTAdapter', 'http://mydomain.com'`"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def url=(url)
|
122
|
+
url.slice!(-1) if url.slice(-1) == '/'
|
123
|
+
@url = url
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
motion_require 'observable'
|
2
|
+
motion_require 'record_array'
|
3
|
+
|
4
|
+
module Loco
|
5
|
+
|
6
|
+
module Savable
|
7
|
+
|
8
|
+
def destroy(&block)
|
9
|
+
adapter = self.class.get_class_adapter
|
10
|
+
unless self.id.nil?
|
11
|
+
adapter.delete_record(self) do |record|
|
12
|
+
self.did_delete
|
13
|
+
block.call(record) if block.is_a? Proc
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def did_create
|
19
|
+
# Override to perform actions after creating the record
|
20
|
+
end
|
21
|
+
alias_method :didCreate, :did_create
|
22
|
+
|
23
|
+
def did_load
|
24
|
+
# Override to perform actions after loading data
|
25
|
+
end
|
26
|
+
alias_method :didLoad, :did_load
|
27
|
+
|
28
|
+
def did_update
|
29
|
+
# Override to perform actions after updating the record
|
30
|
+
end
|
31
|
+
alias_method :didUpdate, :did_update
|
32
|
+
|
33
|
+
def load(id, data)
|
34
|
+
data.merge!({ id: id })
|
35
|
+
self.set_properties(data)
|
36
|
+
self.did_load
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def save(&block)
|
41
|
+
adapter = self.class.get_class_adapter
|
42
|
+
if self.id.nil?
|
43
|
+
adapter.create_record(self) do |record|
|
44
|
+
self.did_create
|
45
|
+
block.call(record) if block.is_a? Proc
|
46
|
+
end
|
47
|
+
else
|
48
|
+
adapter.update_record(self) do |record|
|
49
|
+
self.did_update
|
50
|
+
block.call(record) if block.is_a? Proc
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def serialize(options={})
|
56
|
+
json = {}
|
57
|
+
if options[:root] == false
|
58
|
+
self.class.send(:get_class_properties).each do |key|
|
59
|
+
json[key.to_sym] = self.send(key)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
if options[:root].nil? || options[:root] == true
|
63
|
+
root = self.class.to_s.underscore.to_sym
|
64
|
+
else
|
65
|
+
root = options[:root].to_sym
|
66
|
+
end
|
67
|
+
json[root] = {}
|
68
|
+
self.class.send(:get_class_properties).each do |key|
|
69
|
+
json[root][key.to_sym] = self.send(key)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
json
|
73
|
+
end
|
74
|
+
|
75
|
+
module ClassMethods
|
76
|
+
|
77
|
+
def adapter(adapter_class, *args)
|
78
|
+
if adapter_class.is_a? String
|
79
|
+
@adapter = adapter_class.split('::').inject(Object) {|mod, class_name| mod.const_get(class_name) }.new(*args)
|
80
|
+
else
|
81
|
+
@adapter = adapter_class.new(*args)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def find(id=nil, &block)
|
86
|
+
adapter = self.get_class_adapter
|
87
|
+
if id.nil?
|
88
|
+
# Return all records
|
89
|
+
records = RecordArray.new
|
90
|
+
adapter.find_all(self, records) do |records|
|
91
|
+
block.call(records) if block.is_a? Proc
|
92
|
+
end
|
93
|
+
elsif id.is_a? Array
|
94
|
+
# Return records with given ids
|
95
|
+
records = RecordArray.new
|
96
|
+
adapter.find_many(self, records, id) do |records|
|
97
|
+
block.call(records) if block.is_a? Proc
|
98
|
+
end
|
99
|
+
elsif id.is_a? Hash
|
100
|
+
# Return records matching query
|
101
|
+
records = RecordArray.new
|
102
|
+
adapter.find_query(self, records, id) do |records|
|
103
|
+
block.call(records) if block.is_a? Proc
|
104
|
+
end
|
105
|
+
else
|
106
|
+
record = self.new(id: id)
|
107
|
+
adapter.find(record, id) do |record|
|
108
|
+
block.call(record) if block.is_a? Proc
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def get_class_adapter
|
114
|
+
@adapter ||= Adapter.new
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.included(base)
|
120
|
+
base.extend(ClassMethods)
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -49,7 +49,7 @@ module Loco
|
|
49
49
|
property :content
|
50
50
|
|
51
51
|
def content=(value)
|
52
|
-
|
52
|
+
super
|
53
53
|
self.reloadData
|
54
54
|
end
|
55
55
|
|
@@ -66,12 +66,6 @@ module Loco
|
|
66
66
|
self.class.send(:get_item_view_class)
|
67
67
|
end
|
68
68
|
|
69
|
-
# UITableViewDelegate implementation for returning the number sections in the table view.
|
70
|
-
# @return [Integer]
|
71
|
-
def numberOfSectionsInTableView(tableView)
|
72
|
-
1
|
73
|
-
end
|
74
|
-
|
75
69
|
# UITableViewDelegate implementation for returning the cell at a given indexPath.
|
76
70
|
# @return [Loco::TableViewCell]
|
77
71
|
def tableView(tableView, cellForRowAtIndexPath:indexPath)
|
data/lib/motion-loco/version.rb
CHANGED
data/lib/motion-loco.rb
CHANGED
@@ -2,7 +2,10 @@ unless defined?(Motion::Project::Config)
|
|
2
2
|
raise "This file must be required within a RubyMotion project Rakefile."
|
3
3
|
end
|
4
4
|
|
5
|
-
require '
|
5
|
+
require 'awesome_print_motion'
|
6
|
+
require 'bubble-wrap/core'
|
7
|
+
require 'bubble-wrap/http'
|
6
8
|
require 'motion-require'
|
9
|
+
require 'motion-support/inflector'
|
7
10
|
|
8
11
|
Motion::Require.all(Dir.glob(File.expand_path('../motion-loco/**/*.rb', __FILE__)))
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motion-loco
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Pattison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: awesome_print_motion
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bubble-wrap
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.3.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: motion-require
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +52,20 @@ dependencies:
|
|
38
52
|
- - ~>
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: 0.0.6
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: motion-support
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.4
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.2.4
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rake
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,9 +80,9 @@ dependencies:
|
|
52
80
|
- - ! '>='
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '0'
|
55
|
-
description: ! "
|
56
|
-
properties, and observers.\n
|
57
|
-
views that are easier to position and size
|
83
|
+
description: ! "Motion-Loco is a library for RubyMotion that includes Ember.js inspired\n
|
84
|
+
\ bindings, computed properties, and observers.\n Also
|
85
|
+
included is a set of views that are easier to position and size.\n "
|
58
86
|
email:
|
59
87
|
- brian@brianpattison.com
|
60
88
|
executables: []
|
@@ -62,12 +90,17 @@ extensions: []
|
|
62
90
|
extra_rdoc_files: []
|
63
91
|
files:
|
64
92
|
- README.md
|
93
|
+
- lib/motion-loco/adapter.rb
|
65
94
|
- lib/motion-loco/controller.rb
|
66
95
|
- lib/motion-loco/convenience_methods.rb
|
96
|
+
- lib/motion-loco/fixture_adapter.rb
|
67
97
|
- lib/motion-loco/model.rb
|
68
98
|
- lib/motion-loco/observable.rb
|
69
99
|
- lib/motion-loco/proc.rb
|
100
|
+
- lib/motion-loco/record_array.rb
|
70
101
|
- lib/motion-loco/resizable.rb
|
102
|
+
- lib/motion-loco/rest_adapter.rb
|
103
|
+
- lib/motion-loco/savable.rb
|
71
104
|
- lib/motion-loco/table_view.rb
|
72
105
|
- lib/motion-loco/version.rb
|
73
106
|
- lib/motion-loco/view_controller.rb
|
@@ -96,6 +129,6 @@ rubyforge_project:
|
|
96
129
|
rubygems_version: 2.0.3
|
97
130
|
signing_key:
|
98
131
|
specification_version: 4
|
99
|
-
summary: Library for RubyMotion that includes Ember.js
|
100
|
-
and observers.
|
132
|
+
summary: Library for RubyMotion that includes Ember.js inspired bindings, computed
|
133
|
+
properties, and observers.
|
101
134
|
test_files: []
|