Get Vimeo clip_id from url with regex in objective C - objective-c

Can anybody tell me how to extract the clip_id from a Vimeo url using Obj C regex?
http://vimeo.com/moogaloop.swf?clip_id=12050952&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=56872c&fullscreen=1
I want to extract 12050952.
Thanks.

you can do it with this pattern:
(?<=clip_id=)\d+
It is using positive lookbehind.
Demo: example

I am using a utility class URLParser & its easy and clear.
URLParser *parser = [[[URLParser alloc] initWithURLString:url] autorelease];
NSString *videoId = [parser valueForVariable:#"clip_id"];
Here is the URLParser class
#import <Foundation/Foundation.h>
#interface URLParser : NSObject {
NSArray *variables;
}
#property (nonatomic, retain) NSArray *variables;
- (id)initWithURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;
#end
#implementation URLParser
#synthesize variables;
- (id) initWithURLString:(NSString *)url{
self = [super init];
if (self != nil) {
NSString *string = url;
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"&?"]];
NSString *tempString;
NSMutableArray *vars = [NSMutableArray new];
[scanner scanUpToString:#"?" intoString:nil]; //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:#"&" intoString:&tempString]) {
[vars addObject:[tempString copy]];
}
self.variables = vars;
[vars release];
}
return self;
}
- (NSString *)valueForVariable:(NSString *)varName {
for (NSString *var in self.variables) {
if ([var length] > [varName length]+1 && [[var substringWithRange:NSMakeRange(0, [varName length]+1)] isEqualToString:[varName stringByAppendingString:#"="]]) {
NSString *varValue = [var substringFromIndex:[varName length]+1];
return varValue;
}
}
return nil;
}
- (void) dealloc{
self.variables = nil;
[super dealloc];
}
#end

Related

I am trying to pull the value based on the key in a NSArray in Objective-C that are passed in a URL. How do I get the value form the key? [duplicate]

I have an NSURL:
serverCall?x=a&y=b&z=c
What is the quickest and most efficient way to get the value of y?
Thanks
UPDATE:
Since 2010 when this was written, it seems Apple has released a set of tools for that purpose. Please see the answers below for those.
Old-School Solution:
Well I know you said "the quickest way" but after I started doing a test with NSScanner I just couldn't stop. And while it is not the shortest way, it is sure handy if you are planning to use that feature a lot. I created a URLParser class that gets these vars using an NSScanner. The use is a simple as:
URLParser *parser = [[[URLParser alloc] initWithURLString:#"http://blahblahblah.com/serverCall?x=a&y=b&z=c&flash=yes"] autorelease];
NSString *y = [parser valueForVariable:#"y"];
NSLog(#"%#", y); //b
NSString *a = [parser valueForVariable:#"a"];
NSLog(#"%#", a); //(null)
NSString *flash = [parser valueForVariable:#"flash"];
NSLog(#"%#", flash); //yes
And the class that does this is the following (*source files at the bottom of the post):
URLParser.h
#interface URLParser : NSObject {
NSArray *variables;
}
#property (nonatomic, retain) NSArray *variables;
- (id)initWithURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;
#end
URLParser.m
#implementation URLParser
#synthesize variables;
- (id) initWithURLString:(NSString *)url{
self = [super init];
if (self != nil) {
NSString *string = url;
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"&?"]];
NSString *tempString;
NSMutableArray *vars = [NSMutableArray new];
[scanner scanUpToString:#"?" intoString:nil]; //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:#"&" intoString:&tempString]) {
[vars addObject:[tempString copy]];
}
self.variables = vars;
[vars release];
}
return self;
}
- (NSString *)valueForVariable:(NSString *)varName {
for (NSString *var in self.variables) {
if ([var length] > [varName length]+1 && [[var substringWithRange:NSMakeRange(0, [varName length]+1)] isEqualToString:[varName stringByAppendingString:#"="]]) {
NSString *varValue = [var substringFromIndex:[varName length]+1];
return varValue;
}
}
return nil;
}
- (void) dealloc{
self.variables = nil;
[super dealloc];
}
#end
*if you don't like copying and pasting you can just download the source files - I made a quick blog post about this here.
So many custom url parsers here, remember NSURLComponents is your friend!
Here is an example where I pull out a url encoded parameter for "page"
Swift
let myURL = "www.something.com?page=2"
var pageNumber : Int?
if let queryItems = NSURLComponents(string: myURL)?.queryItems {
for item in queryItems {
if item.name == "page" {
if let itemValue = item.value {
pageNumber = Int(itemValue)
}
}
}
}
print("Found page number: \(pageNumber)")
Objective-C
NSString *myURL = #"www.something.com?page=2";
NSURLComponents *components = [NSURLComponents componentsWithString:myURL];
NSNumber *page = nil;
for(NSURLQueryItem *item in components.queryItems)
{
if([item.name isEqualToString:#"page"])
page = [NSNumber numberWithInteger:item.value.integerValue];
}
"Why reinvent the wheel!" - Someone Smart
I'm pretty sure you have to parse it yourself. However, it's not too bad:
NSString * q = [myURL query];
NSArray * pairs = [q componentsSeparatedByString:#"&"];
NSMutableDictionary * kvPairs = [NSMutableDictionary dictionary];
for (NSString * pair in pairs) {
NSArray * bits = [pair componentsSeparatedByString:#"="];
NSString * key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString * value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[kvPairs setObject:value forKey:key];
}
NSLog(#"y = %#", [kvPairs objectForKey:#"y"]);
In Swift you can use NSURLComponents to parse the query string of an NSURL into an [AnyObject].
You can then create a dictionary from it (or access the items directly) to get at the key/value pairs. As an example this is what I am using to parse a NSURL variable url:
let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
let items = urlComponents?.queryItems as [NSURLQueryItem]
var dict = NSMutableDictionary()
for item in items{
dict.setValue(item.value, forKey: item.name)
}
println(dict["x"])
I've been using this Category: https://github.com/carlj/NSURL-Parameters.
It's small and easy to use:
#import "NSURL+Parameters.h"
...
NSURL *url = [NSURL URLWithString:#"http://foo.bar.com?paramA=valueA&paramB=valueB"];
NSString *paramA = url[#"paramA"];
NSString *paramB = url[#"paramB"];
You can use Google Toolbox for Mac.
It adds a function to NSString to convert query string to a dictionary.
http://code.google.com/p/google-toolbox-for-mac/
It works like a charm
NSDictionary * d = [NSDictionary gtm_dictionaryWithHttpArgumentsString:[[request URL] query]];
Here's a Swift 2.0 extension that provides simple access to parameters:
extension NSURL {
var params: [String: String] {
get {
let urlComponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false)
var items = [String: String]()
for item in urlComponents?.queryItems ?? [] {
items[item.name] = item.value ?? ""
}
return items
}
}
}
Sample usage:
let url = NSURL(string: "http://google.com?test=dolphins")
if let testParam = url.params["test"] {
print("testParam: \(testParam)")
}
I wrote a simple category to extend NSString/NSURL that lets you extract URL query parameters individually or as a dictionary of key/value pairs:
https://github.com/nicklockwood/RequestUtils
I did it using a category method based on #Dimitris solution
#import "NSURL+DictionaryValue.h"
#implementation NSURL (DictionaryValue)
-(NSDictionary *)dictionaryValue
{
NSString *string = [[self.absoluteString stringByReplacingOccurrencesOfString:#"+" withString:#" "]
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"&?"]];
NSString *temp;
NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease];
[scanner scanUpToString:#"?" intoString:nil]; //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:#"&" intoString:&temp])
{
NSArray *parts = [temp componentsSeparatedByString:#"="];
if([parts count] == 2)
{
[dict setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]];
}
}
return dict;
}
#end
All of the current answers are version specific or needlessly wasteful. Why create a dictionary if you only want one value?
Here's a simple answer that supports all iOS versions:
- (NSString *)getQueryParam:(NSString *)name fromURL:(NSURL *)url
{
if (url)
{
NSArray *urlComponents = [url.query componentsSeparatedByString:#"&"];
for (NSString *keyValuePair in urlComponents)
{
NSArray *pairComponents = [keyValuePair componentsSeparatedByString:#"="];
NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
if ([key isEqualToString:name])
{
return [[pairComponents lastObject] stringByRemovingPercentEncoding];
}
}
}
return nil;
}
You can do that easy :
- (NSMutableDictionary *) getUrlParameters:(NSURL *) url
{
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
NSString *tmpKey = [url query];
for (NSString *param in [[url query] componentsSeparatedByString:#"="])
{
if ([tmpKey rangeOfString:param].location == NSNotFound)
{
[params setValue:param forKey:tmpKey];
tmpKey = nil;
}
tmpKey = param;
}
[tmpKey release];
return params;
}
It return Dictionary like it : Key = value
I edited Dimitris' code slightly for better memory management and efficiency. Also, it works in ARC.
URLParser.h
#interface URLParser : NSObject
- (void)setURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;
#end
URLParser.m
#import "URLParser.h"
#implementation URLParser {
NSMutableDictionary *_variablesDict;
}
- (void)setURLString:(NSString *)url {
[_variablesDict removeAllObjects];
NSString *string = url;
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"&?"]];
NSString *tempString;
[scanner scanUpToString:#"?" intoString:nil]; //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:#"&" intoString:&tempString]) {
NSString *dataString = [tempString copy];
NSArray *sepStrings = [dataString componentsSeparatedByString:#"="];
if ([sepStrings count] == 2) {
[_variablesDict setValue:sepStrings[1] forKeyPath:sepStrings[0]];
}
}
}
- (id)init
{
self = [super init];
if (self) {
_variablesDict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (NSString *)valueForVariable:(NSString *)varName {
NSString *val = [_variablesDict valueForKeyPath:varName];
return val;
return nil;
}
-(NSString *)description {
return [NSString stringWithFormat:#"Current Variables: %#", _variablesDict];
}
#end
Quickest is:
NSString* x = [url valueForQueryParameterKey:#"x"];

Is there any way to emulate user's input in XCTest function?

I have method which expects user's input
#implementation TeamFormation
- (void)run {
NSFileHandle *kbd = [NSFileHandle fileHandleWithStandardInput];
NSData *inputData = [kbd availableData];
NSString *option = [[[NSString alloc] initWithData:inputData
encoding:NSUTF8StringEncoding] substringToIndex:1];
NSLog(#"%#",option);
}
#end
Then I would like to cover this method by a test case
#interface TeamFormationTests : XCTestCase
#end
#implementation TeamFormationTests
- (void)testTeamFormation {
TeamFormation *teamFormation = [TeamFormation new];
[teamFormation run];
// emulate user's input here
}
#end
So, how to emulate user's input in test case function?
You have many options how to achieve this. Two obvious below.
Change run to accept an argument
- (void)run to - (void)runWithFileHandle:(NSFileHandle *)handle
your app code can pass stdin filehandle
your test code can pass handle to a file with desired input
Mock it with protocol
Create DataProvider protocol:
#protocol DataProvider
#property(readonly, copy) NSData *availableData;
#end
Make NSFileHandle to conform to this protocol:
#interface NSFileHandle (AvailableDataProvider) <DataProvider>
#end
Store an object implementing this protocol on TeamFormation:
#interface TeamFormation : NSObject
#property (nonatomic, nonnull, strong) id<DataProvider> dataProvider;
- (NSString *)run;
#end
By default, use stdin file handle:
#implementation TeamFormation
- (instancetype)init {
if ((self = [super init]) == nil) {
return nil;
}
_dataProvider = [NSFileHandle fileHandleWithStandardInput];
return self;
}
- (NSString *)run {
NSData *inputData = [self.dataProvider availableData];
return [[[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding] substringToIndex:1];
}
#end
Create TestDataProvider in your test:
#interface TestDataProvider: NSObject<DataProvider>
#property (nonatomic, strong, nonnull) NSData *dataToProvide;
#end
#implementation TestDataProvider
- (instancetype)init {
if ((self = [super init]) == nil) {
return nil;
}
_dataToProvide = [NSData new];
return self;
}
- (NSData *)availableData {
return _dataToProvide;
}
#end
And use it in TestFormationTests:
#implementation TeamFormationTests
- (void)testFormationRun {
TestDataProvider *dataProvider = [TestDataProvider new];
TeamFormation *formation = [TeamFormation new];
formation.dataProvider = dataProvider;
XCTAssertThrows([formation run]);
dataProvider.dataToProvide = [#"foo" dataUsingEncoding:NSUTF8StringEncoding];
XCTAssertEqualObjects([formation run], #"f");
dataProvider.dataToProvide = [#"bar" dataUsingEncoding:NSUTF8StringEncoding];
XCTAssertEqualObjects([formation run], #"b");
}
#end

NSUserDefaults returning nil for some strings in array

I have a custom Object "Woman". I am trying to store the following values in it and save it in a mutable array using NSUserDefaults. The code I use for such is below. I also am using NSCoding in the object.
if (women ==nil) {
women =[[NSMutableArray alloc] init];
}
NSString *string =[NSString stringWithFormat:#"%f", interval];
//store to woman object
Woman* woman = [[Woman alloc] initWithFull:nameOfGirl withdate2:perfectdate withintervalLength:string withperiodLength:[NSString stringWithFormat:#"432000"] withpmsLength:[NSString stringWithFormat:#"432000"]];
[women addObject:woman];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:women] forKey:#"women"];
I use this code to retrieve it:
//pull women from archive
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults valueForKey:#"women"];
if (dataRepresentingSavedArray != nil)
{
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
women = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
women = [[NSMutableArray alloc] init];
}
The result is in the screenshot. What is interesting to me is that the first string makes it but the other ones don't. :
EDIT: Here is my custom class.
.h:
#import <Foundation/Foundation.h>
#interface Woman : NSObject <NSCoding>
#property (nonatomic,strong) NSString *girlname;
#property (nonatomic,strong) NSDate *date2;
#property (nonatomic,strong) NSString *intervalLength;
#property (nonatomic,strong) NSString *periodLength;
#property (nonatomic, strong) NSString *pmsLength;
- (id)initWithFull:(NSString *)girlname withdate2:(NSDate *)date2 withintervalLength:(NSString *)intervalLength withperiodLength:(NSString *)periodLength withpmsLength:(NSString *)pmsLength;
- (id)initWithNoInterval:(NSString *)girlname withdate2:(NSDate *)date2 withperiodLength:(NSString *)periodLength withpmsLength:(NSString *)pmsLength;
- (id)initWithIntervalnoPMSPeriod:(NSString *)girlname withdate2:(NSDate *)date2 withintervalLength:(NSString *)intervalLength;
- (void) encodeWithCoder:(NSCoder*)encode;
- (id) initWithCoder:(NSCoder*)decode;
#end
And the .m:
#import "Woman.h"
#implementation Woman
-(id)initWithFull:(NSString *)girlname withdate2:(NSDate *)date2 withintervalLength:(NSString *)intervalLength withperiodLength:(NSString *)periodLength withpmsLength:(NSString *)pmsLength {
self = [super init];
self.girlname = girlname;
self.date2 = date2;
self.intervalLength = intervalLength;
self.pmsLength = pmsLength;
self.periodLength = periodLength;
return self;
}
-(id)initWithIntervalnoPMSPeriod:(NSString *)girlname withdate2:(NSDate *)date2 withintervalLength:(NSString *)intervalLength {
self = [super init];
self.girlname = girlname;
self.date2 = date2;
self.intervalLength = intervalLength;
return self;
}
-(id)initWithNoInterval:(NSString *)girlname withdate2:(NSDate *)date2 withperiodLength:(NSString *)periodLength withpmsLength:(NSString *)pmsLength {
self = [super init];
self.girlname = girlname;
self.date2 = date2;
self.pmsLength = pmsLength;
self.periodLength = periodLength;
return self;
}
- (id)initWithCoder:(NSCoder *)coder {
if (self = [super init]) {
self.girlname = [coder decodeObjectForKey:#"girlname"];
self.date2 = [coder decodeObjectForKey:#"date2"];
self.intervalLength = [coder decodeObjectForKey:#"intervalLength"];
self.pmsLength = [coder decodeObjectForKey:#"pmsLength"];
self.periodLength = [coder decodeObjectForKey:#"periodLength"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:_girlname forKey:#"girlname"];
[coder encodeObject:_date2 forKey:#"date2"];
[coder encodeBool:_intervalLength forKey:#"intervalLength"];
[coder encodeBool:_pmsLength forKey:#"pmsLength"];
[coder encodeBool:_periodLength forKey:#"periodLength"];
}
#end
Here is also a breakpoint screenshot which shows that the newest object (index 2) has values before it is stores in NSDefaults.
UPDATE: After switching "nameofgirl" and the interval string, the interval string worked, but nameofgirl returned nil. So it's only the first two values working for some reason.
intervalLength, pmsLength and periodLength are NSString objects. Use encodeObject: to encode them.

Property not found on object of type error with method declaration in Objective C

Have a weird error on method declaration and call...
MyObject.h --- declarations. has been trimmed down
#import <Foundation/Foundation.h>
#interface MyObject : NSObject
- (void) useFlattenHTML;
- (NSString *) flattenHTML:(NSString *) inHtml;
- (NSString *) justAStringMethod;
#end
And method defined and called like this...
MyObject.m --- method declaration and usage. Trimmed down
#import "MyObject.h"
#implementation MyObject
- (NSString *) flattenHTML:(NSString *) inHtml {
NSScanner *theScanner;
NSString *text = nil;
theScanner = [NSScanner scannerWithString:inHtml];
while ([theScanner isAtEnd] == NO) {
[theScanner scanUpToString:#"<" intoString:NULL] ;
[theScanner scanUpToString:#">" intoString:&text] ;
inHtml = [inHtml stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"%#>", text] withString:#""];
}
//
inHtml = [inHtml stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
return inHtml;
}
- (NSString *) justAStringMethod
{
// Some calls.
}
- (void) useFlattenHTML
{
NSString* resultStr = [self.flattenHTML #"Some html tagged string"];
NSString* anotherStr = [self.justAStringMethod];
}
#end
I get
Property 'flattenHTML' not found on object of type 'MyObject *'
Maybe because you're using the dot notation in a case where it doesn't make much sense :
in useFlattenHTML method, self.flattenHTML is the same as [self flattenHTML], which doesn't exist, as you only have [self flattenHTML:someString].
On top of that, dot notation is possible, but you should keep it for fields declared as #property only

Issue with save file to Documents NSMutableArray with NSObjects

I'm a newbie iOS developer.
I wrote a small application that save an NSMutableArray array with my objects that derived from NSObject.
Application do the save but the file isn't created in document directory and application can't read.
this issue is both on the simulator and my iPhone 3gs 4.2.1
My NSMutableArray definition inside the appDelegate class:
#property (nonatomic,retain, readwrite) NSMutableArray *places;
My NSObject class:
#import <Foundation/Foundation.h>
#interface Place : NSObject {
NSString *name;
NSString *location;
}
-(id) init:(NSString *)name: (NSString *)location;
#property (retain,nonatomic,readwrite) NSString *name;
#property (retain,nonatomic,readwrite) NSString *location;
#end
My StorageService library class:
#import "StorageService.h"
#implementation StorageService
-(id) init {
self = [super init];
if (self != nil) {
}
return self;
}
-(void) saveArrayToFile:(NSString*) filename : (NSMutableArray *)arrayToSave{
// get full path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *fullPath = [paths objectAtIndex:0];
fullPath = [fullPath stringByAppendingPathComponent:filename];
NSLog(#"Save in %#",fullPath);
[arrayToSave writeToFile:fullPath atomically:YES];
}
-(NSMutableArray*) readArrayFromFile:(NSString *)filename {
// get full path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *fullPath = [paths objectAtIndex:0];
fullPath = [fullPath stringByAppendingPathComponent:filename];
if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {
NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:fullPath];
if (data == nil) {
data = [[NSMutableArray alloc] init];
}
NSLog(#"Read from %#",fullPath);
return data;
} else {
NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:fullPath];
return data;
}
}
-(void) dealloc {
[super dealloc];
}
#end
and My functions in the appDelegate:
-(void) saveApplicationData {
[self.storageService saveArrayToFile : PLACES_FILE : self.places];
}
-(void) loadApplicationData {
self.places = [self.storageService readArrayFromFile:PLACES_FILE];
}
Here is my class that holds constant to filename:
#import <Foundation/Foundation.h>
extern NSString * const PLACES_FILE = #"Places.dat";
#interface ApplicationConstants : NSObject {
}
#end
So what is wrong?
Thank you guys.
What you want is to let Place conform to the NSCoding protocol, to allow for serialization to and from files (and in memory data if wanted)
Extend Place as (I have also changed the name of the init method as your name was against every naming practice iOS has):
#interface Place : NSObject <NSCoding> {
NSString *name;
NSString *location;
}
-(id)initWithName:(NSString *)name location:(NSString *)location;
#property (retain,nonatomic,readwrite) NSString *name;
#property (retain,nonatomic,readwrite) NSString *location;
#end
Your implementation is quite simple but you also need to implement two methods defined by the NSCoding protocol:
#implementation Place
#synthesize name, location;
-(id)initWithName:(NSString *)aName location:(NSString *)aLocation {
self = [super init];
if (self) {
self.name = aName;
self.location = aLocation;
}
return self;
}
-(id)initWithWithCoder:(NSCoder)decoder {
self = [super initWithCoder:decoder];
if (self) {
self.name = [decoder decodeObjectForKey:#"name"];
self.location = [decoder decodeObjectForKey:#"location";
}
return self;
}
-(void)encodeWithCoder:(NSCoder*)encoder {
[encoder encodeObject:self.name forKey:#"name"];
[encoder encodeObject:self.location forKey:#"location"];
[super encodeWithCoder:encoder];
}
#end
With this in place, saving the places array to disk is as easy as:
[NSKeyedArchiver archiveRootObject:places toFile:path];
And decoding just as easy:
places = [[KSKeyUnarchiver unarchiveObjectWithFile:path] retain];
To use writeToFile objects in array need to be plist capable type (NSDate, NSDate, NSString, NSArray, NSDictionary)
Implement NSCoding on the objects in array and use NSKeyedArchiver to serialize/deserialize.
write:
[NSKeyedArchiver archiveRootObject:myArray toFile:self.places];
read:
[NSKeyedUnarchiver unarchiveObjectWithFile:path];
More info can be found here:
Persisting Custom Objects