motion-loco 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|