Merge lost code from model-mapping branch back in

This commit is contained in:
Blake Watters
2010-02-18 12:35:09 -05:00
parent fd696644c6
commit bd694ffb46
11 changed files with 160 additions and 14 deletions

View File

@@ -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 {

View File

@@ -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];

View File

@@ -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];

View File

@@ -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 {

View File

@@ -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

View File

@@ -15,6 +15,7 @@
NSHTTPURLResponse* _httpURLResponse;
NSMutableData* _payload;
NSError* _failureError;
BOOL _loading;
}
/**

View File

@@ -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;
};

View 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

View 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

View File

@@ -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)

View File

@@ -7,7 +7,7 @@
//
#import <UIKit/UIKit.h>
#import "UISpec.h"
#import <UISpec.h>
int main(int argc, char *argv[]) {