mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-01-12 22:51:50 +08:00
Merge lost code from model-mapping branch back in
This commit is contained in:
@@ -101,9 +101,25 @@
|
||||
return @"id";
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Unwind assumptions about the primaryKey
|
||||
*
|
||||
* Right now we make the blanket assumption that Primary Keys are stored as NSNumber values. We
|
||||
* cast from NSStrings into NSNumbers to fix a weird bug Jeremy encountered with the subtle predicate
|
||||
* differences causes nil return values in some cases. This needs to be better understood and the assumptions
|
||||
* unwound.
|
||||
*/
|
||||
+ (id)findByPrimaryKey:(id)value {
|
||||
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"%K = %@", [self primaryKey], value];
|
||||
return [self objectWithPredicate:predicate];
|
||||
id primaryKeyValue = nil;
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
// Cast from string to a number
|
||||
primaryKeyValue = [NSNumber numberWithInt:[(NSString*)value integerValue]];
|
||||
} else {
|
||||
// Make blind assumption here.
|
||||
primaryKeyValue = value;
|
||||
}
|
||||
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"%K = %@", [self primaryKey], primaryKeyValue];
|
||||
return [self objectWithPredicate:predicate];
|
||||
}
|
||||
|
||||
+ (NSDictionary*)elementToPropertyMappings {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
- (BOOL)processResponse:(RKResponse*)response {
|
||||
NSString* errorMessage;
|
||||
NSString* errorMessage = nil;
|
||||
RKRequest* request = response.request;
|
||||
if ([response isFailure]) {
|
||||
[_delegate modelLoaderRequest:response.request didFailWithError:response.failureError response:response model:(id<RKModelMappable>)request.userData];
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
// Don't set the property, both are nil
|
||||
} else if (nil == propertyValue || [propertyValue isKindOfClass:[NSNull class]]) {
|
||||
// Clear out the value to reset it
|
||||
[model setNilValueForKey:propertyName];
|
||||
[model setValue:nil forKey:propertyName];
|
||||
} else if (currentValue == nil || [currentValue isKindOfClass:[NSNull class]]) {
|
||||
// Existing value was nil, just set the property and be happy
|
||||
[model setValue:propertyValue forKey:propertyName];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// RKResponse.m
|
||||
// RestKit
|
||||
// RKFramework
|
||||
//
|
||||
// Created by Blake Watters on 7/28/09.
|
||||
// Copyright 2009 Two Toasters. All rights reserved.
|
||||
@@ -18,6 +18,7 @@
|
||||
if (self = [super init]) {
|
||||
_payload = [[NSMutableData alloc] init];
|
||||
_failureError = nil;
|
||||
_loading = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -53,7 +54,14 @@
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
[_payload appendData:data];
|
||||
if (NO == _loading) {
|
||||
_loading = YES;
|
||||
if ([[_request delegate] respondsToSelector:@selector(requestDidStartLoad:)]) {
|
||||
[[_request delegate] requestDidStartLoad:_request];
|
||||
}
|
||||
}
|
||||
|
||||
[_payload appendData:data];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
|
||||
@@ -62,15 +70,24 @@
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
[connection release];
|
||||
NSDate* receivedAt = [NSDate date];
|
||||
NSDate* receivedAt = [NSDate date]; // TODO - Carry around this timestamp on the response or request?
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[_request HTTPMethod], @"HTTPMethod", [_request URL], @"URL", receivedAt, @"receivedAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKResponseReceivedNotification object:self userInfo:userInfo];
|
||||
[[_request delegate] performSelector:[_request callback] withObject:self];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKResponseReceivedNotification object:self userInfo:userInfo];
|
||||
|
||||
[[_request delegate] performSelector:[_request callback] withObject:self];
|
||||
|
||||
if ([[_request delegate] respondsToSelector:@selector(requestDidFinishLoad:)]) {
|
||||
[[_request delegate] requestDidFinishLoad:_request];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
||||
_failureError = [error retain];
|
||||
[[_request delegate] performSelector:[_request callback] withObject:self];
|
||||
|
||||
if ([[_request delegate] respondsToSelector:@selector(request:didFailLoadWithError:)]) {
|
||||
[[_request delegate] request:_request didFailLoadWithError:error];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString*)localizedStatusCodeString {
|
||||
|
||||
@@ -100,3 +100,16 @@
|
||||
- (void)delete;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* Lifecycle events for RKRequests
|
||||
*
|
||||
* Modeled off of TTURLRequest
|
||||
*/
|
||||
@protocol RKRequestDelegate
|
||||
@optional
|
||||
- (void)requestDidStartLoad:(RKRequest*)request;
|
||||
- (void)requestDidFinishLoad:(RKRequest*)request;
|
||||
- (void)request:(RKRequest*)request didFailLoadWithError:(NSError*)error;
|
||||
- (void)requestDidCancelLoad:(RKRequest*)request; // not yet implemented
|
||||
@end
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
NSHTTPURLResponse* _httpURLResponse;
|
||||
NSMutableData* _payload;
|
||||
NSError* _failureError;
|
||||
BOOL _loading;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
256FD643112C7A5C0077F340 /* libjson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 256FD631112C79750077F340 /* libjson.a */; };
|
||||
256FD651112C7B780077F340 /* RKMappableObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 256FD64F112C7B780077F340 /* RKMappableObject.m */; };
|
||||
256FD652112C7B780077F340 /* RKMappableAssociation.m in Sources */ = {isa = PBXBuildFile; fileRef = 256FD650112C7B780077F340 /* RKMappableAssociation.m */; };
|
||||
256FDE55112DB0B90077F340 /* RKModelMapperSpecModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 256FDE54112DB0B90077F340 /* RKModelMapperSpecModel.m */; };
|
||||
2580B068102E0F1000832D07 /* RKModelLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 2580B066102E0F1000832D07 /* RKModelLoader.h */; };
|
||||
2580B069102E0F1000832D07 /* RKModelLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2580B067102E0F1000832D07 /* RKModelLoader.m */; };
|
||||
2580B0C7102E1EBC00832D07 /* libElementParser.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F4E18DB102DD31E00320118 /* libElementParser.a */; };
|
||||
@@ -67,7 +68,7 @@
|
||||
3F4E18F9102DD38800320118 /* RKParamsDataAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F4E18EA102DD38700320118 /* RKParamsDataAttachment.m */; };
|
||||
3F4E18FA102DD38800320118 /* RKParamsFileAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F4E18EB102DD38700320118 /* RKParamsFileAttachment.h */; };
|
||||
3F4E18FB102DD38800320118 /* RKParamsFileAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F4E18EC102DD38700320118 /* RKParamsFileAttachment.m */; };
|
||||
3F4E18FC102DD38800320118 /* RKRequest.m in Headers */ = {isa = PBXBuildFile; fileRef = 3F4E18ED102DD38700320118 /* RKRequest.m */; };
|
||||
3F4E18FC102DD38800320118 /* RKRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F4E18ED102DD38700320118 /* RKRequest.h */; };
|
||||
3F4E18FD102DD38800320118 /* RKRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F4E18EE102DD38700320118 /* RKRequest.m */; };
|
||||
3F4E18FE102DD38800320118 /* RKRequestSerializable.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F4E18EF102DD38700320118 /* RKRequestSerializable.h */; };
|
||||
3F4E18FF102DD38800320118 /* RKResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F4E18F0102DD38700320118 /* RKResponse.h */; };
|
||||
@@ -225,6 +226,8 @@
|
||||
256FD64D112C7AF50077F340 /* RKMappableAssociation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMappableAssociation.h; sourceTree = "<group>"; };
|
||||
256FD64F112C7B780077F340 /* RKMappableObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMappableObject.m; sourceTree = "<group>"; };
|
||||
256FD650112C7B780077F340 /* RKMappableAssociation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMappableAssociation.m; sourceTree = "<group>"; };
|
||||
256FDE53112DB0B90077F340 /* RKModelMapperSpecModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKModelMapperSpecModel.h; sourceTree = "<group>"; };
|
||||
256FDE54112DB0B90077F340 /* RKModelMapperSpecModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKModelMapperSpecModel.m; sourceTree = "<group>"; };
|
||||
2580B066102E0F1000832D07 /* RKModelLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKModelLoader.h; path = RestKit/RKModelLoader.h; sourceTree = "<group>"; };
|
||||
2580B067102E0F1000832D07 /* RKModelLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKModelLoader.m; sourceTree = "<group>"; };
|
||||
25FCDDD91035BC85005418A7 /* RKManagedModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKManagedModel.h; path = RestKit/RKManagedModel.h; sourceTree = "<group>"; };
|
||||
@@ -250,7 +253,7 @@
|
||||
3F4E18EA102DD38700320118 /* RKParamsDataAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParamsDataAttachment.m; sourceTree = "<group>"; };
|
||||
3F4E18EB102DD38700320118 /* RKParamsFileAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKParamsFileAttachment.h; path = RestKit/RKParamsFileAttachment.h; sourceTree = "<group>"; };
|
||||
3F4E18EC102DD38700320118 /* RKParamsFileAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParamsFileAttachment.m; sourceTree = "<group>"; };
|
||||
3F4E18ED102DD38700320118 /* RKRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequest.m; sourceTree = "<group>"; };
|
||||
3F4E18ED102DD38700320118 /* RKRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKRequest.h; path = RestKit/RKRequest.h; sourceTree = "<group>"; };
|
||||
3F4E18EE102DD38700320118 /* RKRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequest.m; sourceTree = "<group>"; };
|
||||
3F4E18EF102DD38700320118 /* RKRequestSerializable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKRequestSerializable.h; path = RestKit/RKRequestSerializable.h; sourceTree = "<group>"; };
|
||||
3F4E18F0102DD38700320118 /* RKResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKResponse.h; path = RestKit/RKResponse.h; sourceTree = "<group>"; };
|
||||
@@ -352,6 +355,8 @@
|
||||
3F032AA710FFBBCD00F35142 /* RKHouse.m */,
|
||||
3F032AA910FFBC1F00F35142 /* RKResident.h */,
|
||||
3F032AAA10FFBC1F00F35142 /* RKResident.m */,
|
||||
256FDE53112DB0B90077F340 /* RKModelMapperSpecModel.h */,
|
||||
256FDE54112DB0B90077F340 /* RKModelMapperSpecModel.m */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
@@ -422,7 +427,7 @@
|
||||
children = (
|
||||
3F4E18E3102DD38700320118 /* RKClient.h */,
|
||||
3F4E18E4102DD38700320118 /* RKClient.m */,
|
||||
3F4E18ED102DD38700320118 /* RKRequest.m */,
|
||||
3F4E18ED102DD38700320118 /* RKRequest.h */,
|
||||
3F4E18EE102DD38700320118 /* RKRequest.m */,
|
||||
3F4E18F0102DD38700320118 /* RKResponse.h */,
|
||||
3F4E18F1102DD38800320118 /* RKResponse.m */,
|
||||
@@ -517,7 +522,7 @@
|
||||
3F4E18F6102DD38800320118 /* RKParamsAttachment.h in Headers */,
|
||||
3F4E18F8102DD38800320118 /* RKParamsDataAttachment.h in Headers */,
|
||||
3F4E18FA102DD38800320118 /* RKParamsFileAttachment.h in Headers */,
|
||||
3F4E18FC102DD38800320118 /* RKRequest.m in Headers */,
|
||||
3F4E18FC102DD38800320118 /* RKRequest.h in Headers */,
|
||||
3F4E18FE102DD38800320118 /* RKRequestSerializable.h in Headers */,
|
||||
3F4E18FF102DD38800320118 /* RKResponse.h in Headers */,
|
||||
3F4E191A102DD42F00320118 /* NSDictionary+RKRequestSerialization.h in Headers */,
|
||||
@@ -737,6 +742,7 @@
|
||||
256FD523112C6A340077F340 /* Data Model.xcdatamodel in Sources */,
|
||||
256FD651112C7B780077F340 /* RKMappableObject.m in Sources */,
|
||||
256FD652112C7B780077F340 /* RKMappableAssociation.m in Sources */,
|
||||
256FDE55112DB0B90077F340 /* RKModelMapperSpecModel.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
23
Specs/Models/RKModelMapperSpecModel.h
Normal file
23
Specs/Models/RKModelMapperSpecModel.h
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// RKModelMapperSpecModel.h
|
||||
// RestKit
|
||||
//
|
||||
// Created by Blake Watters on 2/18/10.
|
||||
// Copyright 2010 Two Toasters. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface RKModelMapperSpecModel : NSObject {
|
||||
NSString* _name;
|
||||
NSNumber* _age;
|
||||
NSDate* _createdAt;
|
||||
}
|
||||
|
||||
@property (nonatomic,retain) NSString* name;
|
||||
@property (nonatomic,retain) NSNumber* age;
|
||||
@property (nonatomic,retain) NSDate* createdAt;
|
||||
|
||||
@end
|
||||
|
||||
18
Specs/Models/RKModelMapperSpecModel.m
Normal file
18
Specs/Models/RKModelMapperSpecModel.m
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// RKModelMapperSpecModel.m
|
||||
// RestKit
|
||||
//
|
||||
// Created by Blake Watters on 2/18/10.
|
||||
// Copyright 2010 Two Toasters. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RKModelMapperSpecModel.h"
|
||||
|
||||
|
||||
@implementation RKModelMapperSpecModel
|
||||
|
||||
@synthesize name = _name;
|
||||
@synthesize age = _age;
|
||||
@synthesize createdAt = _createdAt;
|
||||
|
||||
@end
|
||||
@@ -128,6 +128,58 @@
|
||||
[expectThat([[result hasMany] count]) should:be(2)];
|
||||
}
|
||||
|
||||
- (void)itShouldNotUpdateNilPropertyToNil {
|
||||
RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease];
|
||||
RKModelMapper* mapper = [[RKModelMapper alloc] init];
|
||||
[mapper updateObject:model ifNewPropertyPropertyValue:nil forPropertyNamed:@"name"];
|
||||
|
||||
[expectThat(model.name) should:be(nil)];
|
||||
}
|
||||
|
||||
- (void)itShouldBeAbleToSetNonNilPropertiesToNil {
|
||||
RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease];
|
||||
model.age = [NSNumber numberWithInt:0];
|
||||
RKModelMapper* mapper = [[RKModelMapper alloc] init];
|
||||
[mapper updateObject:model ifNewPropertyPropertyValue:nil forPropertyNamed:@"age"];
|
||||
|
||||
[expectThat(model.age) should:be(nil)];
|
||||
}
|
||||
|
||||
- (void)itShouldBeAbleToSetNilPropertiesToNonNil {
|
||||
RKModelMapperSpecModel* model = [[OTRestModelMapperTestModel alloc] autorelease];
|
||||
RKModelMapper* mapper = [[RKModelMapper alloc] init];
|
||||
[mapper updateObject:model ifNewPropertyPropertyValue:[NSNumber numberWithInt:0] forPropertyNamed:@"age"];
|
||||
|
||||
[expectThat(model.age) should:be([NSNumber numberWithInt:0])];
|
||||
}
|
||||
|
||||
- (void)itShouldBeAbleToSetNonNilNSStringPropertiesToNonNil {
|
||||
RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease];
|
||||
RKModelMapper* mapper = [[RKModelMapper alloc] init];
|
||||
|
||||
model.name = @"Bob";
|
||||
[mapper updateObject:model ifNewPropertyPropertyValue:@"Will" forPropertyNamed:@"name"];
|
||||
[expectThat(model.name) should:be(@"Will")];
|
||||
}
|
||||
|
||||
- (void)itShouldBeAbleToSetNonNilNSNumberPropertiesToNonNil {
|
||||
RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease];
|
||||
RKModelMapper* mapper = [[RKModelMapper alloc] init];
|
||||
|
||||
model.age = [NSNumber numberWithInt:16];
|
||||
[mapper updateObject:model ifNewPropertyPropertyValue:[NSNumber numberWithInt:17] forPropertyNamed:@"age"];
|
||||
[expectThat(model.age) should:be([NSNumber numberWithInt:17])];
|
||||
}
|
||||
|
||||
- (void)itShouldBeAbleToSetNonNilNSDatePropertiesToNonNil {
|
||||
RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease];
|
||||
RKModelMapper* mapper = [[RKModelMapper alloc] init];
|
||||
|
||||
model.createdAt = [NSDate date];
|
||||
[mapper updateObject:model ifNewPropertyPropertyValue:[NSDate dateWithTimeIntervalSince1970:0] forPropertyNamed:@"createdAt"];
|
||||
[expectThat(model.createdAt) should:be([NSDate dateWithTimeIntervalSince1970:0])];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RKModelMapperSpec (Private)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "UISpec.h"
|
||||
#import <UISpec.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user