From 4b5be044d4e156de6cd5fb5995142ef4c70435f7 Mon Sep 17 00:00:00 2001 From: kingiol Date: Mon, 13 Jan 2014 10:33:47 +0800 Subject: [PATCH 1/7] support arc --- Archiver.h | 2 +- Archiver.m | 4 ++-- NSObject+NSCoding.m | 53 +++++++++++++++++---------------------------- 3 files changed, 23 insertions(+), 36 deletions(-) diff --git a/Archiver.h b/Archiver.h index a905107..8b20f07 100644 --- a/Archiver.h +++ b/Archiver.h @@ -10,7 +10,7 @@ @interface Archiver : NSObject { - + } + (id)retrieve:(NSString *)key; diff --git a/Archiver.m b/Archiver.m index ff38994..73f6124 100644 --- a/Archiver.m +++ b/Archiver.m @@ -14,7 +14,7 @@ + (id)retrieve:(NSString *)key { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *filePath = [documentsDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@.archive", key]]; - return [[[NSKeyedUnarchiver unarchiveObjectWithFile:filePath] retain] autorelease]; + return [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; } + (BOOL)persist:(id)object key:(NSString *)key { @@ -29,7 +29,7 @@ + (BOOL)delete:(NSString *)key { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *filePath = [documentsDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@.archive", key]]; - return [fileManager removeItemAtPath:filePath error:NULL]; + return [fileManager removeItemAtPath:filePath error:NULL]; } + (BOOL)deleteEverything { diff --git a/NSObject+NSCoding.m b/NSObject+NSCoding.m index b7bf528..c598cfe 100644 --- a/NSObject+NSCoding.m +++ b/NSObject+NSCoding.m @@ -14,7 +14,7 @@ @implementation NSObject (NSCoding) - (NSMutableDictionary *)propertiesForClass:(Class)klass { - NSMutableDictionary *results = [[[NSMutableDictionary alloc] init] autorelease]; + NSMutableDictionary *results = [[NSMutableDictionary alloc] init]; unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(klass, &outCount); @@ -68,7 +68,10 @@ - (void)autoEncodeWithCoder:(NSCoder *)coder { if ([[type componentsSeparatedByString:@"\""] count] > 1) { className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1]; Class class = NSClassFromString(className); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" value = [self performSelector:NSSelectorFromString(key)]; +#pragma clang diagnostic pop // only decode if the property conforms to NSCoding if([class conformsToProtocol:@protocol(NSCoding)]){ @@ -123,7 +126,7 @@ - (void)autoEncodeWithCoder:(NSCoder *)coder { break; default: break; - } + } } } @@ -133,7 +136,6 @@ - (void)autoDecode:(NSCoder *)coder { NSString *type = [properties objectForKey:key]; id value; NSNumber *number; - unsigned int addr; NSInteger i; CGFloat f; BOOL b; @@ -143,81 +145,66 @@ - (void)autoDecode:(NSCoder *)coder { long longValue; unsigned unsignedValue; short shortValue; - Ivar ivar; - double *varIndex; NSString *className; switch ([type characterAtIndex:0]) { case '@': // object if ([[type componentsSeparatedByString:@"\""] count] > 1) { - className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1]; + className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1]; Class class = NSClassFromString(className); // only decode if the property conforms to NSCoding if ([class conformsToProtocol:@protocol(NSCoding )]){ - value = [[coder decodeObjectForKey:key] retain]; - addr = (NSInteger)&value; - object_setInstanceVariable(self, [key UTF8String], *(id**)addr); + value = [coder decodeObjectForKey:key]; + [self setValue:value forKey:key]; } } break; case 'c': // bool - number = [coder decodeObjectForKey:key]; + number = [coder decodeObjectForKey:key]; b = [number boolValue]; - addr = (NSInteger)&b; - object_setInstanceVariable(self, [key UTF8String], *(NSInteger**)addr); + [self setValue:@(b) forKey:key]; break; case 'f': // float - number = [coder decodeObjectForKey:key]; + number = [coder decodeObjectForKey:key]; f = [number floatValue]; - addr = (NSInteger)&f; - object_setInstanceVariable(self, [key UTF8String], *(NSInteger**)addr); + [self setValue:@(f) forKey:key]; break; - case 'd': // double + case 'd': // double number = [coder decodeObjectForKey:key]; d = [number doubleValue]; - if ((ivar = class_getInstanceVariable([self class], [key UTF8String]))) { - varIndex = (double *)(void **)((char *)self + ivar_getOffset(ivar)); - *varIndex = d; - } + [self setValue:@(d) forKey:key]; break; case 'i': // int number = [coder decodeObjectForKey:key]; i = [number intValue]; - addr = (NSInteger)&i; - object_setInstanceVariable(self, [key UTF8String], *(NSInteger**)addr); + [self setValue:@(i) forKey:key]; break; case 'L': // unsigned long number = [coder decodeObjectForKey:key]; ul = [number unsignedLongValue]; - addr = (NSInteger)&ul; - object_setInstanceVariable(self, [key UTF8String], *(NSInteger**)addr); + [self setValue:@(ul) forKey:key]; break; case 'Q': // unsigned long long number = [coder decodeObjectForKey:key]; ull = [number unsignedLongLongValue]; - addr = (NSInteger)&ull; - object_setInstanceVariable(self, [key UTF8String], *(NSInteger**)addr); + [self setValue:@(ull) forKey:key]; break; case 'l': // long number = [coder decodeObjectForKey:key]; longValue = [number longValue]; - addr = (NSInteger)&longValue; - object_setInstanceVariable(self, [key UTF8String], *(NSInteger**)addr); + [self setValue:@(longValue) forKey:key]; break; case 'I': // unsigned number = [coder decodeObjectForKey:key]; unsignedValue = [number unsignedIntValue]; - addr = (NSInteger)&unsignedValue; - object_setInstanceVariable(self, [key UTF8String], *(NSInteger**)addr); + [self setValue:@(unsignedValue) forKey:key]; break; case 's': // short number = [coder decodeObjectForKey:key]; shortValue = [number shortValue]; - addr = (NSInteger)&shortValue; - object_setInstanceVariable(self, [key UTF8String], *(NSInteger**)addr); + [self setValue:@(shortValue) forKey:key]; break; - default: break; } From 2e7e1c43a520ef42f3cd1ea184baa7e1b8a53565 Mon Sep 17 00:00:00 2001 From: kingiol Date: Mon, 13 Jan 2014 11:11:02 +0800 Subject: [PATCH 2/7] add podsepc and license --- LICENSE | 19 +++++++++++++++++++ NSObject-NSCoding.podspec | 12 ++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 LICENSE create mode 100644 NSObject-NSCoding.podspec diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c0e9839 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 NSObject-NSCoding-Kingiol + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/NSObject-NSCoding.podspec b/NSObject-NSCoding.podspec new file mode 100644 index 0000000..87d97ca --- /dev/null +++ b/NSObject-NSCoding.podspec @@ -0,0 +1,12 @@ +Pod::Spec.new do |s| + s.name = "NSObject-NSCoding" + s.version = "1.0" + s.summary = "Automatic NSCoding and persistence implementation" + s.homepage = "https://github.com/kingiol/NSObject-NSCoding" + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { "greenisus" => "greenisus@gmail.com", "kingiol" => "kingxiaokang@gmail.com" } + s.platform = :ios + s.source = { :git => "https://github.com/kingiol/NSObject-NSCoding.git", :tag => "1.0" } + s.source_files = '*.{h,m}' + s.requires_arc = true +end \ No newline at end of file From 654d9cbe495803000f563d469d749cac20bfb6f3 Mon Sep 17 00:00:00 2001 From: kingiol Date: Tue, 14 Jan 2014 22:17:27 +0800 Subject: [PATCH 3/7] add CI yml file --- .travis.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2ec406f --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: objective-c \ No newline at end of file From 723beb571e258be2aea867d1bb749ba45250308d Mon Sep 17 00:00:00 2001 From: kingiol Date: Tue, 14 Jan 2014 22:26:19 +0800 Subject: [PATCH 4/7] add ci status bar --- README | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README b/README index 1fe586f..104acb1 100644 --- a/README +++ b/README @@ -1,6 +1,9 @@ NSObject+NSCoding and Archiver ------------------------------ +build by Kingiol +[![Build Status](https://travis-ci.org/kingiol/NSObject-NSCoding.png?branch=master)](https://travis-ci.org/kingiol/NSObject-NSCoding) + Mike Mayo Rackspace Mobile Apps mike@overhrd.com From c4a7db028b4b5a3a174a48c240f5364d37609002 Mon Sep 17 00:00:00 2001 From: kingiol Date: Tue, 14 Jan 2014 22:30:24 +0800 Subject: [PATCH 5/7] modify readme.md --- README => README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename README => README.md (99%) diff --git a/README b/README.md similarity index 99% rename from README rename to README.md index 104acb1..dd90ad2 100644 --- a/README +++ b/README.md @@ -2,6 +2,7 @@ NSObject+NSCoding and Archiver ------------------------------ build by Kingiol + [![Build Status](https://travis-ci.org/kingiol/NSObject-NSCoding.png?branch=master)](https://travis-ci.org/kingiol/NSObject-NSCoding) Mike Mayo @@ -60,4 +61,4 @@ In your class implementation, call the automatic methods: [self autoDecode:coder]; } return self; -} +} \ No newline at end of file From df0b9321c0bfbceb6a4d98d5c756e0af2c955c99 Mon Sep 17 00:00:00 2001 From: Harlan Date: Wed, 12 Feb 2014 15:55:43 -0500 Subject: [PATCH 6/7] Added Markdown formatting, License, and CocoaPods information to README. --- README.md | 65 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index dd90ad2..e0a79e4 100644 --- a/README.md +++ b/README.md @@ -11,54 +11,67 @@ mike@overhrd.com twitter: @greenisus These are some simple classes to make object persistence with NSCoding easier. This code was extracted from -the Rackspace Cloud / OpenStack iOS app at http://launchpad.net/openstack-ios +the Rackspace Butt / OpenStack iOS app at http://launchpad.net/openstack-ios -INSTALLATION +# Installation -To install, simply drag Archiver.h, Archiver.m, NSObject+NSCoding.h, and NSObject+NSCoding.m into your project. +CocoaPods +- + +NSObject-NSCoding is easiest to install using [CocoaPods](http://cocoapods.org). +Simply add this line to your Podfile + + pod 'NSObject-NSCoding' + +and run `pod install` + +Static +- + +If you prefer not to use CocoaPods, simply drag Archiver.h, Archiver.m, NSObject+NSCoding.h, and NSObject+NSCoding.m into your project. Then, right click Frameworks in Groups & Files and choose Add -> Existing Frameworks... and choose libobjc.A.dylib. -USAGE +# Usage --- Archiver +Archiver +- This class will read and write objects that conform to the NSCoding protocol to disk. -Archiver Usage: - -SomeClass *myObject = [[[SomeClass alloc] init] autorelease]; -myObject.someProperty = @"Hello world"; + SomeClass *myObject = [[[SomeClass alloc] init] autorelease]; + myObject.someProperty = @"Hello world"; -[Archiver persist:myObject key:@"myObject"]; + [Archiver persist:myObject key:@"myObject"]; -// later on somewhere else... + // later on somewhere else... -SomeClass *myObject = [Archiver retrieve:@"myObject"]; + SomeClass *myObject = [Archiver retrieve:@"myObject"]; --- NSObject+NSCoding +NSObject+NSCoding +- This category simplifies implementing NSCoding by iterating over the properties of your class and encoding/decoding them for you. It persists primitives (such as ints and floats) as well as any objects that conform to NSCoding. -NSObject+NSCoding Usage: - In your class header, conform to NSCoding: -@interface Model : NSObject { -//... -} + @interface Model : NSObject In your class implementation, call the automatic methods: -- (void)encodeWithCoder:(NSCoder *)coder { - [self autoEncodeWithCoder:coder]; -} + - (void)encodeWithCoder:(NSCoder *)coder { + [self autoEncodeWithCoder:coder]; + } -- (id)initWithCoder:(NSCoder *)coder { - if (self = [super init]) { - [self autoDecode:coder]; + - (id)initWithCoder:(NSCoder *)coder { + if (self = [super init]) { + [self autoDecode:coder]; + } + return self; } - return self; -} \ No newline at end of file + +# License + +NSObject+NSCoding is released under the MIT license. A full description of that license is available in the LICENSE file. From 275d743b8a7f17e1b4a2687c43f3c22f6800d609 Mon Sep 17 00:00:00 2001 From: Harlan Date: Wed, 12 Feb 2014 15:57:50 -0500 Subject: [PATCH 7/7] Fixed cloud-to-butt errors. I should really uninstall that plugin. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e0a79e4..ec1bbe9 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ mike@overhrd.com twitter: @greenisus These are some simple classes to make object persistence with NSCoding easier. This code was extracted from -the Rackspace Butt / OpenStack iOS app at http://launchpad.net/openstack-ios +the Rackspace Cloud / OpenStack iOS app at http://launchpad.net/openstack-ios # Installation @@ -28,9 +28,9 @@ and run `pod install` Static - -If you prefer not to use CocoaPods, simply drag Archiver.h, Archiver.m, NSObject+NSCoding.h, and NSObject+NSCoding.m into your project. +If you prefer not to use CocoaPods, simply drag `Archiver.h`, `Archiver.m`, `NSObject+NSCoding.h`, and `NSObject+NSCoding.m` into your project. -Then, right click Frameworks in Groups & Files and choose Add -> Existing Frameworks... and choose libobjc.A.dylib. +Then, right click `Frameworks` in `Groups & Files` and choose `Add` -> `Existing Frameworks...` and choose `libobjc.A.dylib`. # Usage