Objective-Cãç¹ã«iOSçšã®
ActiveRecordãã¿ãŒã³ã®å¥ã®å®è£
ãå
±æããããšæããŸãã
iOSéçºã§
CoreDataã䜿çšãå§ããã°ããã®ãšãã§ãããã®çžäºäœçšã¯äœããã®åœ¢ã§åçŽåã§ãããšèããããŠããŸããã ãã°ããããŠãããRubyOnRailsã®ActiveRecordã«äŒã£ããšãããäœãæ¬ ããŠããã®ããããããŸããã
githubãå°ãæ€çŽ¢ããŠãå€ãã®å®è£
ãèŠã€ããŸããããããŸããŸãªçç±ã§ãããã奜ãã§ã¯ãããŸããã§ããã CoreDataçšã«äœæããããã®ããããŸãããç§ã¯å¥œãã§ã¯ãããŸãããä»ã®ãã®ã§ã¯ãæã§ããŒãã«ãäœæããããçã®SQLã¯ãšãªãäœæããå¿
èŠããããŸãã ãŸããå Žåã«ãã£ãŠã¯ã³ãŒããã²ã©ãã²ã©ãã£ãã®ã§ãç§ã¯æã
èªåã§ããŸããããã«æžããªãããšããããŸãããå²ãŸããif / switch / if / switchããã®å·šå€§ãªãã§ã³ã¹ãå€ãããŸãã
æçµçã«ãCoreDataãšãŠãŒã¶ãŒã®SQLã䜿çšããã«èªè»¢è»ãäœæããããšã«ããŸããã
ãã®éçºã®äž»ãªçç±ã¯ãéçºã«èå³ãããããšã§ãã
ããããã¹ãŠã®çµæã§ãã
ãããŠãç«ã®äžã«ã¯ãå¯èœæ§ãšå®è£
ã«ã€ããŠã®å°ããªèª¬æããããŸãïŒå®éãå€ãã®ããã¹ããšã³ãŒããèšäºã®æåŸã®èŠçŽïŒã
ããŒãã«äœæ
æåã®åé¡ã¯ããŒãã«ã®äœæã§ããã
CoreDataã®å Žåãäœãäœæããå¿
èŠã¯ãªãããšã³ãã£ãã£ãèšè¿°ããã ãã§ãããšã¯CDãåŠçããŸãã
ç§ã¯ãããããè¯ãæŽçããæ¹æ³ã«ã€ããŠé·ãéèããŠããŸãããããã°ãããããšãããç§ã«æ°ä»ããŸããã
Objective-Cã§ã¯ãä»»æã®ã¯ã©ã¹ã®ãã¹ãŠã®ãµãã¯ã©ã¹ã®ãªã¹ããååŸã§ããããã«ãã®ãã¹ãŠã®ããããã£ã®ãªã¹ããååŸã§ããŸãã ãããã£ãŠããšã³ãã£ãã£ã®èª¬æã¯ã¯ã©ã¹ã®ç°¡åãªèª¬æã«ãªããŸãããã®æ
å ±ãåéããããã«åºã¥ããŠSQLã¯ãšãªãäœæããã ãã§ãã
ãšã³ãã£ãã£ã®èª¬æ
@interface User : ActiveRecord @property (nonatomic, retain) NSString *name; @end
ãã¹ãŠã®ãµãã¯ã©ã¹ãååŸãã
static NSArray *class_getSubclasses(Class parentClass) { int numClasses = objc_getClassList(NULL, 0); Class *classes = NULL; classes = malloc(sizeof(Class) * numClasses); numClasses = objc_getClassList(classes, numClasses); NSMutableArray *result = [NSMutableArray array]; for (NSInteger i = 0; i < numClasses; i++) { Class superClass = classes[i]; do{ superClass = class_getSuperclass(superClass); } while(superClass && superClass != parentClass); if (superClass == nil) { continue; } [result addObject:classes[i]]; } return result; }
ãã¹ãŠã®ããããã£ãåºæ¬ã¯ã©ã¹ãŸã§ååŸãã
Class BaseClass = NSClassFromString(@"NSObject"); id CurrentClass = aRecordClass; while(nil != CurrentClass && CurrentClass != BaseClass){ unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(CurrentClass, &outCount); for (i = 0; i < outCount; i++) {
ããŒã¿å
æè»æ§ãé«ããããã«ãåºæ¬ããŒã¿åïŒintãdoubleãªã©ïŒãæŸæ£ããã¯ã©ã¹ãããŒãã«ãã£ãŒã«ããšããŠã®ã¿äœ¿çšããå¿
èŠããããŸããã
ãããã£ãŠãä»»æã®ã¯ã©ã¹ãããŒãã«ãã£ãŒã«ããšããŠäœ¿çšã§ããŸããå¯äžã®èŠä»¶ã¯ãããèªäœãä¿åããã³ããŒãã§ããå¿
èŠãããããšã§ãã
ãããè¡ãã«ã¯ãARRepresentationProtocolãå®è£
ããå¿
èŠããããŸã
@protocol ARRepresentationProtocol @required + (const char *)sqlType; - (NSString *)toSql; + (id)fromSql:(NSString *)sqlData; @end
ã«ããŽãªã䜿çšããŠFoundationãã¬ãŒã ã¯ãŒã¯ã¿ã€ãã«ãããã®ã¡ãœãããå®è£
ããŸãã
-NSDecimalNumber-å®æ°
-NSNumber-æŽæ°
-NSString-ããã¹ã
-NSData-ããã
-NSDate-æ¥ä»ïŒå®æ°ïŒ
ãã ãããããã®ã¯ã©ã¹ã®ã»ããã¯ãã€ã§ãæ¡åŒµã§ããããã»ã©é£ãããããŸããã
TransformableããŒã¿åã®CoreDataã䜿çšããŠãåãããšãå®çŸã§ããŸããããããã©ã®ããã«äœ¿çšãããã¯ãŸã ããããŸããã
ã¬ã³ãŒãã®CRUD
äœæãã
æ°ããã¬ã³ãŒããäœæããããã»ã¹ã¯éåžžã«ã·ã³ãã«ã§ééçã§ãã
User *user = [User newRecord]; user.name = @"Alex"; [user save];
èªã
ãã¹ãŠã®ã¬ã³ãŒããååŸãã
NSArray *users = [User allRecords];
å€ãã®å Žåããã¹ãŠã®ã¬ã³ãŒããå¿
èŠã§ã¯ãªãããããã£ã«ã¿ãŒã®å®è£
ãè¿œå ããŸãããããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
æŽæ°ãã
User *user = [User newRecord]; user.name = @"Alex"; [user save]; NSArray *users = [User allRecords]; User *userForUpdate = [users first]; userForUpdate.name = @"John"; [userForUpdate update];
ActiveRecordã¯ãã¹ãŠã®ããããã£ã®å€æŽãç£èŠããæŽæ°æã«ã¯å€æŽããããã£ãŒã«ãã®ã¿ãæŽæ°ãããªã¯ãšã¹ããäœæããŸãã
åé€ãã
NSArray *users = [User allRecords]; User *userForRemove = [users first]; [userForRemove dropRecord];
ãã¹ãŠã®ã¬ã³ãŒãã«ã¯ãåé€ã«äœ¿çšãããidïŒNSNumberïŒããããã£ããããŸãã
äžèŠãªãã£ãŒã«ã
ããŒã¿ããŒã¹ã«ä¿åããå¿
èŠã®ãªããã£ãŒã«ãã¯ã©ãã§ããïŒ ç¡èŠããŠãã ãã:)
ãããè¡ãã«ã¯ãã¯ã©ã¹ã®å®è£
ã§æ¬¡ã®æ§æãè¿œå ããå¿
èŠããããŸããããã¯åçŽãªãã¯ãã·ã¹ãã ã§ãã
@implementation User ... @synthesize ignoredProperty; ... ignore_fields_do( ignore_field(ignoredProperty) ) ... @end
æ€èšŒ
éçºã§èªåèªèº«ã«èšå®ããèŠæ±ã®1ã€ã¯ãæ€èšŒã®ãµããŒãã§ãã
çŸåšãå¯çšæ§ãšäžææ§ã®2çš®é¡ã®æ€èšŒãå®è£
ãããŠããŸãã
æ§æã¯åçŽã§ãcolãã¯ãã䜿çšããŸãã ããã«ãã¯ã©ã¹ã¯ARValidatableProtocolãå®è£
ããå¿
èŠããããŸãããŠãŒã¶ãŒããã®èŠæ±ã¯ãããŸãããããã¯ãããã䜿çšããªãã¯ã©ã¹ã®æ€èšŒã¡ã«ããºã ãéå§ããªãããã«ããããã§ãã
ããã«ããŠãŒã¶ãŒèªèº«ãè¿œå ã§ããã«ã¹ã¿ã ããªããŒã¿ãŒã®ãµããŒããå®è£
ããŸããã
ãããè¡ãã«ã¯ãARValidatorProtocolãå®è£
ããæ€èšŒæžã¿ã®ã¯ã©ã¹ã§èšè¿°ããå¿
èŠãããæ€èšŒã¯ã©ã¹ãäœæããå¿
èŠããããŸãã
ARValidatorProtocol
@protocol ARValidatorProtocol <NSObject> @optional - (NSString *)errorMessage; @required - (BOOL)validateField:(NSString *)aField ofRecord:(id)aRecord; @end
ã«ã¹ã¿ã æ€èšŒ
ãšã©ãŒåŠç
saveãupdateãisValidã¡ãœããã¯ããŒã«å€ãè¿ããŸã; false / NOãè¿ãããå Žåããšã©ãŒã®ãªã¹ããååŸã§ããŸã
[user errors];
ãã®åŸãã¯ã©ã¹ARErrorã®ãªããžã§ã¯ãã®é
åãè¿ãããŸã
@interface ARError : NSObject @property (nonatomic, copy) NSString *modelName; @property (nonatomic, copy) NSString *propertyName; @property (nonatomic, copy) NSString *errorName; - (id)initWithModel:(NSString *)aModel property:(NSString *)aProperty error:(NSString *)anError; @end
ãã®ã¯ã©ã¹ã«ã¯è©³çŽ°ãªãšã©ãŒã¡ãã»ãŒãžã¯å«ãŸããŸããããããŒã«ã©ã€ãºãããã¡ãã»ãŒãžãäœæããŠã¢ããªã±ãŒã·ã§ã³ãŠãŒã¶ãŒã«è¡šç€ºã§ããããŒã¯ãŒãã®ã¿ãå«ãŸããŸãã
移è¡
移è¡ã¯ããªããã£ãã¬ãã«ã§å®è£
ãããŸãããšã³ãã£ãã£ãžã®æ°ãããã£ãŒã«ãã®è¿œå ãŸãã¯æ°ãããšã³ãã£ãã£ã®è¿œå ã«ã®ã¿å¿çããŸãã
移è¡ã䜿çšããããã«ãã©ãã«ãç»é²ããå¿
èŠã¯ãããŸããã
ã¢ããªã±ãŒã·ã§ã³ãåããŠèµ·åãããšããã¹ãŠã®ããŒãã«ãäœæããããã®åŸã®èµ·åæã«ãæ°ãããã£ãŒã«ããŸãã¯ããŒãã«ãååšãããã©ããã確èªãããååšããå Žåã¯ãããŒãã«ã¯ãšãªãå€æŽãããŸãã
ããŒãã«æ§é ã®å€æŽã®ãã§ãã¯ãã€ã³ã¹ã¿ã³ã¹åããªãããã«ãActiveRecordãåŒã³åºãåã«æ¬¡ã®ã¡ãã»ãŒãžãéä¿¡ããå¿
èŠããããŸã
[ActiveRecord disableMigrations];
ååŒ
ãã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããæ©èœãå®è£
ããŸãããããã«ã¯ãããã¯ã䜿çšãããŸã
[ActiveRecord transaction:^{ User *alex = [User newRecord]; alex.name = @"Alex"; [alex save]; rollback }];
rollback-ã¿ã€ãARExceptionã®äŸå€ãã¹ããŒããéåžžã®ãã¯ãã
Tarnzaktsiiã¯ãé害ãçºçããå Žåã®ããŒã«ããã¯ã ãã§ãªããã¬ã³ãŒããè¿œå ããéã®ã¯ãšãªå®è¡ã®é床ãäžããããã«ã䜿çšã§ããŸãã
ãããžã§ã¯ãã®1ã€ã¯ã9000以äžã®ã¬ã³ãŒããäœæããããšãããšãã«ã²ã©ããã¬ãŒãããããŸããã ãã³ãã®å®è¡æéã¯ãBEGINãã©ã³ã¶ã¯ã·ã§ã³ã§ã©ããããåŸãçŽ180ç§ã§ãã; ... COMMIT; æéã¯çŽ4ã5ç§ã«ççž®ãããŸããã ã ãããç§ã¯ç¥ããªã人ã«ã¢ããã€ã¹ããŸããã³ãã¥ãã±ãŒã·ã§ã³ãº
RoRã§ã®ActiveRecordã®å®è£
ã«ç²Ÿéãããšãããšã³ãã£ãã£éã®é¢ä¿ãç°¡åã«äœæã§ããããšã«æºè¶³ããŸããã æŠããŠããã®ã·ã³ãã«ãã¯ããã®ãã¬ãŒã ã¯ãŒã¯ãäœæããããã®æåã®åææ¡ä»¶ãšãªããŸããã ãããŠä»ãç§ã¯èªè»¢è»ã®æãéèŠãªæ©èœã¯ããšã³ãã£ãã£éã®æ¥ç¶ãšãããã®çžå¯Ÿçãªã·ã³ãã«ãã§ãããšèããŠããŸãã
HasMany <-> BelongsTo
belongs_to_dec belonsg_to_impãã¯ãã¯3ã€ã®ãã©ã¡ãŒã¿ãŒãåãå
¥ããŸãïŒãã³ã³ã¿ã¯ããããŠããã¯ã©ã¹ã®ååãã²ãã¿ãŒã®ååãäŸåé¢ä¿ã®ã¿ã€ãã
äŸåé¢ä¿ã«ã¯ãARDependencyNullifyãšARDependencyDestroyã®2çš®é¡ããããŸãã1ã€ç®ã¯ã¢ãã«ãåé€ãããšé¢ä¿ãç¡å¹ã«ãªãã2ã€ç®ã¯é¢é£ãããã¹ãŠã®ãšã³ãã£ãã£ãåé€ãããŸãã
ãã®é¢ä¿ã®ãã£ãŒã«ãã¯ã¢ãã«åãšäžèŽããå°æåã§å§ãŸãå¿
èŠããããŸãã°ã«ãŒã<-> groupId
ãŠãŒã¶ãŒ<-> userId
ContentManager <-> contentManagerId
EMCategory <-> eMCategory //å°ãäžåšçšã§ãããæŽå²çã«ã¯
ãã£ãŒãããã¯ïŒHasManyïŒ
BelongsToã¿ã€ãã®éä¿¡ãšåãã§ãã
èŠããŠããã¹ãäž»ãªããšïŒãªã³ã¯ãäœæããåã«ãäž¡æ¹ã®ã¬ã³ãŒããä¿åããå¿
èŠããããŸããä¿åããªããšãIDããªãããªã³ã¯ãããã«é¢é£ä»ããããŸããHasManyThrough
ãã®æ¥ç¶ãäœæããã«ã¯ãå¥ã®ã¢ãã«ãäžéã¢ãã«ãäœæããå¿
èŠããããŸãã
äžéãã€ã³ãã£ã³ã°ã¢ãã«
ãã®æ¥ç¶ã«ã¯ãHasManyãšåãæ¬ ç¹ããããŸãã
* _Dec / * _ impãã¯ãã¯ãã«ããŒã¡ãœãããè¿œå ããŠãªã³ã¯ãè¿œå ããŸã
set#ModelName:(ActiveRecord *)aRecord; // BelongsTo add##ModelName:(ActiveRecord *)aRecord; // HasMany, HasManyThrough remove##ModelName:(ActiveRecord *)aRecord; // HasMany, HasManyThrough
ã¯ãšãªãã£ã«ã¿ãŒ
éåžžã«é »ç¹ã«ãããŒã¿ããŒã¹ããã®éžæãäœããã®æ¹æ³ã§ãã£ã«ã¿ãªã³ã°ããå¿
èŠããããŸãã
-ãããã³ãã¬ãŒãã«å¯Ÿå¿ããã¬ã³ãŒãã®æ€çŽ¢ïŒUISearchBarïŒ
-1000ã®ãã¡5ã¬ã³ãŒãã®ã¿ãããŒãã«ã«åºå
-ãéããåçã®ããŒã¿ããŒã¹ããŒãããååŸããã«ãã¬ã³ãŒãã®ããã¹ããã£ãŒã«ãã®ã¿ãåä¿¡ãã
-ãŸã å€ãã®ãªãã·ã§ã³:)
æåã¯ãããããã¹ãŠã䟿å©ãªåœ¢åŒã§å®è£
ããæ¹æ³ãèããããŸããã§ããããRubyãšãã®åºæã®ãé
延ããæãåºããæçµçã«ãèŠæ±ã«å¿ããŠã®ã¿ã¬ã³ãŒããååŸããããä»»æã®é åºã§ãã£ã«ã¿ãŒãåãå
¥ããã¯ã©ã¹ãäœæããããšã«ããŸããã
ããããã®çµæã§ãã
å¶é/ãªãã»ãã
NSArray *users = [[[User lazyFetcher] limit:5] fetchRecords]; NSArray *users = [[[User lazyFetcher] offset:5] fetchRecords]; NSArray *users = [[[[User lazyFetcher] offset:5] limit:2] fetchRecords];
ã®ã¿/ãé€ã
ARLazyFetcher *fetcher = [[User lazyFetcher] only:@"name", @"id", nil]; ARLazyFetcher *fetcher = [[User lazyFetcher] except:@"veryBigImage", nil];
ã©ãã§
iActiveRecordã¯WHEREåºæ¬æ¡ä»¶ããµããŒãããŸã
- (ARLazyFetcher *)whereField:(NSString *)aField equalToValue:(id)aValue; - (ARLazyFetcher *)whereField:(NSString *)aField notEqualToValue:(id)aValue; - (ARLazyFetcher *)whereField:(NSString *)aField in:(NSArray *)aValues; - (ARLazyFetcher *)whereField:(NSString *)aField notIn:(NSArray *)aValues; - (ARLazyFetcher *)whereField:(NSString *)aField like:(NSString *)aPattern; - (ARLazyFetcher *)whereField:(NSString *)aField notLike:(NSString *)aPattern; - (ARLazyFetcher *)whereField:(NSString *)aField between:(id)startValue and:(id)endValue; - (ARLazyFetcher *)where:(NSString *)aFormat, ...;
åãããšãããªãã¿ã®äŸ¿å©ãªNSPredicate'ovã®ã¹ã¿ã€ã«ã§èª¬æã§ããŸãã
NSArray *ids = [NSArray arrayWithObjects: [NSNumber numberWithInt:1], [NSNumber numberWithInt:15], nil]; NSString *username = @"john"; ARLazyFetcher *fetcher = [User lazyFetcher]; [fetcher where:@"'user'.'name' = %@ or 'user'.'id' in %@", username, ids, nil]; NSArray *records = [fetcher fetchRecords];
åå ãã
ç§ã¯ãããèªåã§äœ¿çšããããšã¯ã»ãšãã©ãããŸããã§ããããå®å
šãæãããã«å®è£
ããå¿
èŠããããšå€æããŸããã
- (ARLazyFetcher *)join:(Class)aJoinRecord useJoin:(ARJoinType)aJoinType onField:(NSString *)aFirstField andField:(NSString *)aSecondField;
ããŸããŸãªã¿ã€ãã®çµåããµããŒããããŠããŸã
-ARJoinLeft
-ARJoinRight
-ARJoinInner
-ARJoinOuter
ååã¯ããèªäœãç©èªã£ãŠãããšæããŸãã
1ã€ã®å°ããªæŸèæããã®æ©èœã«é¢é£ä»ããããŠãããããçµåã¬ã³ãŒããååŸããã«ã¯ãåŒã³åºãå¿
èŠããããŸã
- (NSArray *)fetchJoinedRecords;
ã®ä»£ããã«
- (NSArray *)fetchRecords;
ãã®ã¡ãœããã¯ãããŒããšã³ãã£ãã£åã§ãããå€ãããŒã¿ããŒã¹ããã®ããŒã¿ã§ããèŸæžããé
åãè¿ããŸãã
ä»åã
- (ARLazyFetcher *)orderBy:(NSString *)aField ascending:(BOOL)isAscending; - (ARLazyFetcher *)orderBy:(NSString *)aField;
ä¿ç®¡
ããŒã¿ããŒã¹ã¯ãã£ãã·ã¥ãšããã¥ã¡ã³ãã®äž¡æ¹ã«ä¿åã§ããŸããããã¥ã¡ã³ãã«ä¿åããå Žåãããã¯ã¢ãããåæããå±æ§ããã¡ã€ã«ã«è¿œå ãããŸã
u_int8_t b = 1; setxattr([[url path] fileSystemRepresentation], "com.apple.MobileBackup", &b, 1, 0, 0);
ããã§ãªãå Žåãã¢ããªã±ãŒã·ã§ã³ã¯AppleããæåŠãåãåããŸãã
ãŸãšã
githubãããžã§ã¯ãã¯
iActiveRecordã§ãã
ç¹åŸŽ
- ARCãµããŒã
- ãŠãã³ãŒãã®ãµããŒã
- 移è¡
- æ€èšŒãã«ã¹ã¿ã ããªããŒã¿ãŒã®ãµããŒãä»ã
- ååŒ
- ã«ã¹ã¿ã ããŒã¿å
- ã³ãã¥ãã±ãŒã·ã§ã³ïŒBelongsToãHasManyãHasManyThroughïŒ
- ä»åã
- ãã£ã«ã¿ãŒïŒwhere = ã! =ãINãNOT INãªã©ïŒ
- åäŒ
- CocoaPodsã®ãµããŒã
ãããã«
çµè«ã
æ£åœåããããã« ãç§ã¯ãããžã§ã¯ãããã ã®æ¥œãã¿ã®ããã«å§ãŸã£ããšèšããããšæããŸãããããŠãããã¯æçµçã«ããããã®ãæ±ããã³ãŒãããããã«ããä»ã®æçšãªæ©èœãè¿œå ããèšç»ã§ãéçºãç¶ããŠããŸãã
é©åãªæ¹å€ãèããŠããããã§ãã
PSã¯LANã«ãšã©ãŒã¡ãã»ãŒãžãæžã蟌ã¿ãŸãã