NSDictionary Object Disappearing - objective-c

My app uses a plist to save data between sessions. I use the three below methods to save and read data from the plist file. However, I've been having an enormous problem.
When I save my data, all 12 key/value pairs are set up perfectly in the NSMutableDictionary (I've checked this in the debugger, all 12 pairs are definitely there). However, when I read the data, only 11 pairs show up. The missing 12th key/value pair is "Tab," an NSMutableArray. All other data types are either NSString or NSNumber.
Property declaration for Tab:
#property (strong, nonatomic) NSMutableArray *tab;
Code:
- (NSString *)dataFileName
{
NSError *err = nil;
NSURL *dir = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSAllDomainsMask appropriateForURL:nil create:YES error:&err];
NSString *path = [[dir path] stringByAppendingString:#"/employeeListData.plist"];
return path; //path has not been declared yet
}
- (void)saveDataToFile
{
NSMutableArray *a = [NSMutableArray array];
for (int c = 0; c < [self.employeeList count]; c++) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
id r = [self.employeeList objectAtIndex:c];
[dictionary setObject:[r username] forKey:#"username"];
[dictionary setObject:[r passWord] forKey:#"passWord"];
[dictionary setObject:[r employeeName] forKey:#"employeeName"];
[dictionary setObject:[r grade] forKey:#"grade"];
[dictionary setObject:[r email] forKey:#"email"];
[dictionary setObject:[r phone] forKey:#"phone"];
[dictionary setObject:[r freePeriods] forKey:#"freePeriods"];
[dictionary setObject:[r committee] forKey:#"committee"];
[dictionary setValue:[NSNumber numberWithBool:[r hasKey]] forKey:#"hasKey"];
[dictionary setObject:[r hours] forKey:#"hours"];
[dictionary setObject:[NSArray arrayWithArray:[r tab]] forKey:#"tab"];
float num = [r tabTotal];
NSNumber *floatObject = [NSNumber numberWithFloat:num];
[dictionary setObject:floatObject forKey:#"tabTotal"];
[a addObject:dictionary];
}
[a writeToFile:[self dataFileName] atomically:YES];
}
- (void)readDataFromFile
{
[self createEmployeeList];
NSArray *tempArray = [NSArray arrayWithContentsOfFile:[self dataFileName]];
for (int d = 0; d < [tempArray count]; d++) {
Employee *person = [[Employee alloc] init];
NSDictionary *dict = [tempArray objectAtIndex:d];
[person setUsername:[dict objectForKey:#"username"]];
[person setPassWord:[dict objectForKey:#"passWord"]];
[person setEmployeeName:[dict objectForKey:#"employeeName"]];
[person setGrade:[dict objectForKey:#"grade"]];
[person setEmail:[dict objectForKey:#"email"]];
[person setPhone:[dict objectForKey:#"phone"]];
[person setFreePeriods:[dict objectForKey:#"freePeriods"]];
[person setCommittee:[dict objectForKey:#"committee"]];
[person setHasKey:[[dict valueForKey:#"hasKey"] boolValue]];
[person setHours:[dict objectForKey:#"hours"]];
[person setTab:[[dict objectForKey:#"tab"] mutableCopy]];
NSNumber *floatNumber = dict[#"tabTotal"];
float floatValue = floatNumber.floatValue;
[person setTabTotal:floatValue];
[self.employeeList addObject:person];
}
}

The problem was due to my array of custom objects. I added in the following code in my save method:
NSMutableArray *x = [NSMutableArray array];
for (int y = 0; y < [[r tab]count]; y++) {
NSMutableDictionary *items = [NSMutableDictionary dictionary];
id z = [[r tab] objectAtIndex:y];
[items setObject:[z itemName] forKey:#"tabName"];
[items setObject:[NSNumber numberWithInt:[z price]] forKey:#"tabPrice"];
[x addObject:items];
}
[dictionary setObject:x forKey:#"tab"];
And the following code in my read method:
NSMutableArray *things = [[NSMutableArray alloc] init];
things = dict[#"tab"];
person.tab = [[NSMutableArray alloc] init];
for (int g = 0; g < things.count; g++) {
TabItem *item = [[TabItem alloc] init];
NSDictionary *ion = [things objectAtIndex:g];
[item setItemName:[ion objectForKey:#"tabName"]];
[item setPrice:[[ion objectForKey:#"tabPrice"] intValue]];
[person.tab addObject:item];
}
Since arrays of custom objects can't be stored in NSDictionaries, I used a smaller version of my larger save and read methods to accomplish the task. Full, updated code can be found below.
- (void)saveDataToFile
{
NSMutableArray *a = [NSMutableArray array];
for (int c = 0; c < [self.employeeList count]; c++) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
id r = [self.employeeList objectAtIndex:c];
[dictionary setObject:[r username] forKey:#"username"];
[dictionary setObject:[r passWord] forKey:#"passWord"];
[dictionary setObject:[r employeeName] forKey:#"employeeName"];
[dictionary setObject:[r grade] forKey:#"grade"];
[dictionary setObject:[r email] forKey:#"email"];
[dictionary setObject:[r phone] forKey:#"phone"];
[dictionary setObject:[r freePeriods] forKey:#"freePeriods"];
[dictionary setObject:[r committee] forKey:#"committee"];
[dictionary setValue:[NSNumber numberWithBool:[r hasKey]] forKey:#"hasKey"];
[dictionary setObject:[r hours] forKey:#"hours"];
NSMutableArray *x = [NSMutableArray array];
for (int y = 0; y < [[r tab]count]; y++) {
NSMutableDictionary *items = [NSMutableDictionary dictionary];
id z = [[r tab] objectAtIndex:y];
[items setObject:[z itemName] forKey:#"tabName"];
[items setObject:[NSNumber numberWithInt:[z price]] forKey:#"tabPrice"];
[x addObject:items];
}
[dictionary setObject:x forKey:#"tab"];
[dictionary setObject:[NSNumber numberWithInt:[r tabTotal]] forKey:#"tabTotal"];
[a addObject:dictionary];
}
[a writeToFile:[self dataFileName] atomically:YES];
}
- (void)readDataFromFile
{
[self createEmployeeList];
NSArray *tempArray = [NSArray arrayWithContentsOfFile:[self dataFileName]];
for (int d = 0; d < [tempArray count]; d++) {
Employee *person = [[Employee alloc] init];
NSDictionary *dict = [tempArray objectAtIndex:d];
[person setUsername:[dict objectForKey:#"username"]];
[person setPassWord:[dict objectForKey:#"passWord"]];
[person setEmployeeName:[dict objectForKey:#"employeeName"]];
[person setGrade:[dict objectForKey:#"grade"]];
[person setEmail:[dict objectForKey:#"email"]];
[person setPhone:[dict objectForKey:#"phone"]];
[person setFreePeriods:[dict objectForKey:#"freePeriods"]];
[person setCommittee:[dict objectForKey:#"committee"]];
[person setHasKey:[[dict valueForKey:#"hasKey"] boolValue]];
[person setHours:[dict objectForKey:#"hours"]];
NSMutableArray *things = [[NSMutableArray alloc] init];
things = dict[#"tab"];
person.tab = [[NSMutableArray alloc] init];
for (int g = 0; g < things.count; g++) {
TabItem *item = [[TabItem alloc] init];
NSDictionary *ion = [things objectAtIndex:g];
[item setItemName:[ion objectForKey:#"tabName"]];
[item setPrice:[[ion objectForKey:#"tabPrice"] intValue]];
[person.tab addObject:item];
}
[person setTabTotal:[[dict objectForKey:#"tabTotal"] intValue]];
[self.employeeList addObject:person];
}
}

Related

Objective-C / ALAssetslibrary - How can i change my method to work synchronously

I have implemented a method that retrieve correctly the informations about images using the Alassetslibrary. As you know, it works asynchronously but in my case i need that it works synchronously. I have only to read the informations about images and return to the method. My application as only one view that doesn't need a refresh. How can i modify my method? At the moment the line "return xmlList;" result always null, but i know that the assets are correctly read in the block because i have used a NSlog.
-(NSString *) getPhotos{
NSMutableArray *idList = [[NSMutableArray alloc] init];
NSMutableArray *widthList = [[NSMutableArray alloc] init];
NSMutableArray *heightList = [[NSMutableArray alloc] init];
NSMutableArray *orientationList = [[NSMutableArray alloc] init];
NSMutableArray *dateList = [[NSMutableArray alloc] init];
__block XMLWriter* xmlWriter = [[XMLWriter alloc]init];
__block NSString *xmlList;
__block NSString *test;
__block ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
__block NSString *description = [[NSString alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
if (asset){
NSString *description = [asset description];
NSRange first = [description rangeOfString:#"URLs:"];
NSRange second = [description rangeOfString:#"?id="];
NSString *path = [description substringWithRange: NSMakeRange(first.location + first.length, second.location - (first.location + first.length))];
[idList addObject:path];
NSDictionary *data = [[asset defaultRepresentation] metadata];
NSNumber *width = [[[asset defaultRepresentation] metadata] objectForKey:#"PixelWidth"];
NSString *widthString = [NSString stringWithFormat:#"%#", width];
[widthList addObject:widthString];
NSNumber *height = [[[asset defaultRepresentation] metadata] objectForKey:#"PixelHeight"];
NSString *heightString = [NSString stringWithFormat:#"%#", height];
[heightList addObject:heightString];
NSNumber *orientation = [[[asset defaultRepresentation] metadata] objectForKey:#"Orientation"];
NSString *orientationString = [NSString stringWithFormat:#"%#", orientation];
if(orientationString != NULL){
[orientationList addObject:orientationString];
} else {
NSString *noOrientation = [[NSString alloc] init];
noOrientation = #"No orientation avaiable";
[dateList addObject:noOrientation];
}
NSString *dateString = [[[asset defaultRepresentation] metadata] objectForKey:#"DateTime"];
if(dateString != NULL){
[dateList addObject:dateString];
} else {
NSString *noDate = [[NSString alloc] init];
noDate = #"No date avaiable";
[dateList addObject:noDate];
}
}
}];
}
if (group == nil){
[xmlWriter writeStartDocumentWithEncodingAndVersion:#"UTF-8" version:#"1.0"];
[xmlWriter writeStartElement:#"Data"];
int i = 0;
for(i = 0; i<=[idList count]-1; i++){
[xmlWriter writeStartElement:#"Photo"];
[xmlWriter writeAttribute:#"Id" value:[idList objectAtIndex:i]];
[xmlWriter writeAttribute:#"Width" value:[widthList objectAtIndex:i]];
[xmlWriter writeAttribute:#"Height" value:[heightList objectAtIndex:i]];
[xmlWriter writeAttribute:#"Orientation" value:[orientationList objectAtIndex:i]];
[xmlWriter writeAttribute:#"Date" value:[dateList objectAtIndex:i]];
[xmlWriter writeEndElement:#"Photo"];
}
[xmlWriter writeEndElement:#"Data"];
[xmlWriter writeEndDocument];
xmlList = [xmlWriter toString];
}
} failureBlock:^(NSError *error) {
NSLog(#"error enumerating AssetLibrary groups %#\n", error);
}];
return xmlList;
}
Ok at the end i have resolve my problem. I have used the NSConditionLock Class. Here there is the updated code:
-(NSString *) getPhotos{
enum { WDASSETURL_PENDINGREADS = 1, WDASSETURL_ALLFINISHED = 0};
NSMutableArray *idList = [[NSMutableArray alloc] init];
NSMutableArray *widthList = [[NSMutableArray alloc] init];
NSMutableArray *heightList = [[NSMutableArray alloc] init];
NSMutableArray *orientationList = [[NSMutableArray alloc] init];
NSMutableArray *dateList = [[NSMutableArray alloc] init];
__block XMLWriter* xmlWriter = [[XMLWriter alloc]init];
__block NSString *xmlList;
__block NSString *test;
__block NSConditionLock * assetsReadLock = [[NSConditionLock alloc] initWithCondition:WDASSETURL_PENDINGREADS];
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__block ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
__block NSString *description = [[NSString alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
if (asset){
NSString *description = [asset description];
NSRange first = [description rangeOfString:#"URLs:"];
NSRange second = [description rangeOfString:#"?id="];
NSString *path = [description substringWithRange: NSMakeRange(first.location + first.length, second.location - (first.location + first.length))];
[idList addObject:path];
NSDictionary *data = [[asset defaultRepresentation] metadata];
NSNumber *width = [[[asset defaultRepresentation] metadata] objectForKey:#"PixelWidth"];
NSString *widthString = [NSString stringWithFormat:#"%#", width];
[widthList addObject:widthString];
NSNumber *height = [[[asset defaultRepresentation] metadata] objectForKey:#"PixelHeight"];
NSString *heightString = [NSString stringWithFormat:#"%#", height];
[heightList addObject:heightString];
NSNumber *orientation = [[[asset defaultRepresentation] metadata] objectForKey:#"Orientation"];
NSString *orientationString = [NSString stringWithFormat:#"%#", orientation];
if(orientationString != NULL){
[orientationList addObject:orientationString];
} else {
NSString *noOrientation = [[NSString alloc] init];
noOrientation = #"No orientation avaiable";
[dateList addObject:noOrientation];
}
NSString *dateString = [[[asset defaultRepresentation] metadata] objectForKey:#"DateTime"];
if(dateString != NULL){
[dateList addObject:dateString];
} else {
NSString *noDate = [[NSString alloc] init];
noDate = #"No date avaiable";
[dateList addObject:noDate];
}
}
}];
}
if (group == nil){
[xmlWriter writeStartDocumentWithEncodingAndVersion:#"UTF-8" version:#"1.0"];
[xmlWriter writeStartElement:#"Data"];
int i = 0;
for(i = 0; i<=[idList count]-1; i++){
[xmlWriter writeStartElement:#"Photo"];
[xmlWriter writeAttribute:#"Id" value:[idList objectAtIndex:i]];
[xmlWriter writeAttribute:#"Width" value:[widthList objectAtIndex:i]];
[xmlWriter writeAttribute:#"Height" value:[heightList objectAtIndex:i]];
[xmlWriter writeAttribute:#"Orientation" value:[orientationList objectAtIndex:i]];
[xmlWriter writeAttribute:#"Date" value:[dateList objectAtIndex:i]];
[xmlWriter writeEndElement:#"Photo"];
}
[xmlWriter writeEndElement:#"Data"];
[xmlWriter writeEndDocument];
xmlList = [xmlWriter toString];
[assetsReadLock lock];
[assetsReadLock unlockWithCondition:WDASSETURL_ALLFINISHED];
}
} failureBlock:^(NSError *error) {
NSLog(#"error enumerating AssetLibrary groups %#\n", error);
[assetsReadLock lock];
[assetsReadLock unlockWithCondition:WDASSETURL_ALLFINISHED];
}];
});
[assetsReadLock lockWhenCondition:WDASSETURL_ALLFINISHED];
[assetsReadLock unlock];
NSLog(#"XML: %#", xmlList);
return xmlList;
}

Memory don't release

Here is my code:
-(void) encodeStationsBack
{
if (context == nil)
{
context = [(radioAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After managedObjectContext: %#", context);
}
// here is JSON parsing
int i=0;
int count = stations.count;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Station" inManagedObjectContext:context];
NSMutableArray* parsedData = [[NSMutableArray alloc] init];
while(stations.count > 0) {
NSString*string = [[NSString alloc] initWithString:[stations objectAtIndex:0]];
if (![string isEqual:#""]) {
NSMutableDictionary*dic = [[NSMutableDictionary alloc]init];
// NSLog(#"%#", string);
NSData*data = [[NSData alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]];
NSMutableDictionary* pars;
#try {
pars = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
}
#catch (NSException *exception) {
NSLog(#"%# , %#", exception.description, exception.reason);
}
#finally {
}
// NSMutableDictionary* pars =[[NSMutableDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data
// options:kNilOptions/*NSJSONReadingMutableContainers*/ error:nil]];
[pars retain];
[dic setObject:[[pars objectForKey:#"nm"]mutableCopy] forKey:#"nm"];
[dic setObject:[[pars objectForKey:#"btr"]mutableCopy] forKey:#"btr"];
[dic setObject:[[pars objectForKey:#"id"]mutableCopy] forKey:#"id"];
[dic setObject:[[pars objectForKey:#"cntr"]mutableCopy] forKey:#"cntr"];
[dic setObject:[[pars objectForKey:#"gnr"]mutableCopy] forKey:#"gnr"];
[pars release];
#try {
[parsedData addObject:[NSDictionary dictionaryWithDictionary:dic]];
}
#catch (NSException* exc) {
NSLog(#"%#, %#", exc.description, exc.reason);
}
[dic release];
[data release];
[string release];
[stations removeObjectAtIndex:0];
// if (i%1000==0) {
// NSLog(#"nnnn %i %i", parsedData.count, stations.count);
// }
i++;
float k = count;
k = (i + 1)/k;
[self performSelectorOnMainThread:#selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
}
else {
[stations removeObjectAtIndex:0];
}
}
[stations release];
i = 0;
while (parsedData.count > 0) {
Station*station = [[Station alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
[station setName:[[[parsedData objectAtIndex:0] objectForKey:#"nm"]mutableCopy]];
[station setBit:[[[parsedData objectAtIndex:0] objectForKey:#"btr"]mutableCopy]];
[station setEnabled:[NSNumber numberWithInt:1]];
//encoding id of the station
unsigned int tempInt;
NSScanner *scanner= [[NSScanner alloc] init];
scanner = [NSScanner scannerWithString:[[parsedData objectAtIndex:0] objectForKey:#"id"]];
[scanner scanHexInt:&tempInt];
NSNumber *numb = [[NSNumber alloc] init];
numb = [NSNumber numberWithInt:tempInt];
numb = [NSNumber numberWithInt: ([numb integerValue] ^ sec )];
[station setNumber: [NSNumber numberWithInt:[numb intValue]]];
//encoding country ID
tempInt = 0;
scanner = [NSScanner scannerWithString:[[parsedData objectAtIndex:0] objectForKey:#"cntr"]];
[scanner scanHexInt:&tempInt];
numb = [NSNumber numberWithInt:tempInt];
numb = [NSNumber numberWithInt:(([numb integerValue] ^ sec ))];
if (![numb isEqualToNumber:[NSNumber numberWithInt:n]])
{
[station setCountryID:[NSNumber numberWithInt:[numb intValue]]];
}
else
{
[station setCountryID:[NSNumber numberWithInt:-1]];
}
//encoding genre ID
tempInt = 0;
scanner = [NSScanner scannerWithString:[[parsedData objectAtIndex:0] objectForKey:#"gnr"]];
[scanner scanHexInt:&tempInt];
numb = [NSNumber numberWithInt:tempInt];
numb = [NSNumber numberWithInt:(([numb integerValue] ^ sec ))];
if (![numb isEqualToNumber:[NSNumber numberWithInt:N]])
{
[station setGenerID:[NSNumber numberWithInt:[numb intValue]]];
}
else
{
[station setGenerID: [NSNumber numberWithInt:-1]];
}
[station setOrder:[NSNumber numberWithInt:i]];
[context insertObject:station];
float k = count;
k = (i + 1)/k;
[self performSelectorOnMainThread:#selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
// NSLog(#"%i", i);
[parsedData removeObjectAtIndex:0];
[station release];
// [station release];
i++;
}
[parsedData release];
[self performSelectorOnMainThread:#selector(deleteAllFromDB) withObject:nil waitUntilDone:YES];
[context save:nil];
}
I can't understand why my app uses so mutch memory (~150 mb). I tryed to look on my code with analyze. Nothing interestig xCode thinks that all is ok.
Here is what I see with Instruments
Instruments
you have alloced in the loop and de alloced outside the loop in scanner there are other mistakes like this. have a look and make a code review.
id obj1 =[[pars objectForKey:#"nm"]mutableCopy];
[dic setObject:obj1 forKey:#"nm"];
[obj1 release]; // No memory leak
[dic setObject:[[pars objectForKey:#"btr"]mutableCopy] forKey:#"btr"];//memory leak
[dic setObject:[[pars objectForKey:#"id"]mutableCopy] forKey:#"id"];//memory leak
[dic setObject:[[pars objectForKey:#"cntr"]mutableCopy] forKey:#"cntr"];//memory leak
[dic setObject:[[pars objectForKey:#"gnr"]mutableCopy] forKey:#"gnr"];//memory leak
Change all setObject:forKey:

RestKit: mapping array of key-value pairs to NSDictionary

Webservice sends me JSON that looks like that:
[
{"key":"key1","value":"value1"},
{"key":"key2","value":"value2"},
{"key":"key3","value":"value3"}
]
How should I set up RestKit mapping to get the following NSDictionary?
#{ #"key1" : #"value1", #"key2" : #"value2", #"key3": #"value3" }
This may help you, try this.
NSDictionary *dict1 = [[NSMutableDictionary alloc] init];
NSArray *arr = [[NSArray alloc] initWithArray:<Parse the array here from RESTkit>];
for (int i = 0;i < [arr count], i++)
{
NSDictionary *dict = [arr objectAtIndex:i];
NSString *key = [dict objectForKey:#"key"];
NSString *value = [dict objectForKey:#"value"];
[dict1 setObject:value forKey:key];
}
NSLog(#" Dictionary %#", dict1);
[dict1 release];

Fix unicode characters in NSString

I am getting a string response from the Google Directions API that contains characters that are supposed to represent a different-language character. Similiar to Ƨ³, similiar to these type of characters. I think the characters are portugese, but anyways my string contains like this:
\U00e3o
(I am not sure if those are zeroes or 'O's)
I am not sure what the technical term for these characters are, but how can I fix them in my string so they print properly.
Thank you
UPDATE:
I have updated my question title with the correct term 'unicode'.
I have checked a few questions:
NSString Unicode display
Detect Unicode characters in NSString on iPhone
iOS HTML Unicode to NSString?
And a few others. I have followed the answer, but the unicode characters are not fixed.
UPDATE:
Here is my code to get the response from GDirection.
Forming the request and getting a response:
AFHTTPClient *_httpClient = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://maps.googleapis.com/"]];
[_httpClient registerHTTPOperationClass: [AFJSONRequestOperation class]];
[_httpClient setDefaultHeader:#"Accept" value:#"application/json"];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[parameters setObject:[NSString stringWithFormat:#"%f,%f", location.coordinate.latitude, location.coordinate.longitude] forKey:#"origin"];
[parameters setObject:[NSString stringWithFormat:#"%f,%f", location2.coordinate.latitude, location2.coordinate.longitude] forKey:#"destination"];
[parameters setObject:#"false" forKey:#"sensor"];
[parameters setObject:#"driving" forKey:#"mode"];
[parameters setObject:#"metric" forKey: #"units"];
NSMutableURLRequest *request = [_httpClient requestWithMethod:#"GET" path: #"maps/api/directions/json" parameters:parameters];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
AFHTTPRequestOperation *operation = [_httpClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSInteger statusCode = operation.response.statusCode;
if (statusCode == 200) {
[self parseResponse:responseObject];
} else {
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { }];
[_httpClient enqueueHTTPRequestOperation:operation];
}
Retrieving information from response object:
- (void)parseResponse:(NSDictionary *)response {
NSString *status = [response objectForKey: #"status"];
if (![status isEqualToString: #"OK"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat: #"Google Directions Response Status: %#", status] delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[alert show];
}
else {
NSArray *routes = [response objectForKey:#"routes"];
NSDictionary *routePath = [routes lastObject];
if (routePath) {
NSString *overviewPolyline = [[routePath objectForKey: #"overview_polyline"] objectForKey:#"points"];
legs = [routePath valueForKey: #"legs"];
if (legs) {
/* DIRECTION SET ================================================================================================================================
*/
directionOverview = [[NSMutableDictionary alloc] init];
NSString *legsDis = [NSString stringWithFormat: #"%#", [[legs valueForKey: #"distance"] valueForKey: #"text"]];
NSString *kmDistance = [self cutStringToPreference: legsDis];
if (kmDistance) {
[directionOverview setObject:kmDistance forKey: #"distance"];
milesLabel.text = kmDistance;
milesLabel.font = [UIFont fontWithName:#"interstate" size: 20.0];
}
NSString *durationText = [NSString stringWithFormat: #"%#", [[legs valueForKey: #"duration"] valueForKey: #"text"]];
durationText = [self cutStringToPreference: durationText];
if (durationText) {
[directionOverview setObject:durationText forKey: #"duration"];
}
NSString *startAddress = [NSString stringWithFormat: #"%#", [legs valueForKey: #"start_address"]];
startAddress = [self cutStringToPreference: startAddress];
NSString *endAddress = [NSString stringWithFormat: #"%#", [legs valueForKey: #"end_address"]];
endAddress = [self cutStringToPreference: endAddress];
[directionOverview setObject:startAddress forKey: #"origin"];
[directionOverview setObject:endAddress forKey: #"destination"];
NSArray *steps = [legs valueForKey: #"steps"];
if (steps) {
instructionArray = [[NSMutableArray alloc] init];
durationArray = [[NSMutableArray alloc] init];
distanceArray = [[NSMutableArray alloc] init];
int number = [[[steps lastObject] valueForKey: #"html_instructions"] count];
for (int i = 1; i <= number; ++i) {
NSString *instruction = [[[steps lastObject] valueForKey: #"html_instructions"] objectAtIndex: i-1];
instruction = [self cutStringToPreference: instruction];
instruction = [self flattenHTML: instruction];
instruction = [self stringByDecodingHTMLEntitiesInString: instruction];
[instructionArray addObject: instruction];
NSString *distance = [[[[steps lastObject] valueForKey: #"distance"] objectAtIndex: i-1] valueForKey: #"text"];
[distanceArray addObject: distance];
NSString *duration = [[[[steps lastObject] valueForKey: #"duration"] objectAtIndex: i-1] valueForKey: #"text"];
[durationArray addObject: duration];
}
}
}
_path = [self decodePolyLine:overviewPolyline];
NSInteger numberOfSteps = _path.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [_path objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[self.mapView addOverlay:polyLine];
}
}
}
Displaying the text in a label:
NSString *overviewAddressText = [NSString stringWithFormat: #"%# to %#", [directionOverview objectForKey: #"origin"], [directionOverview objectForKey: #"destination"]];
overviewAddress.text = overviewAddressText;
UPDATE:
Image of label
So as you can see, in the label, the text contains this kind of substring: S/U00e3o, which is a word that has an unsupported character. How can I fix that so that unicode turns into this: São

Objective C How to fill rangeOfString of a NSArray?

I wonder if it is possible to fill rangeOfString objects of a NSArray. Because I have a long list of objects for after rangeOfString:
NSArray biglist´s count is higher than list´s count.
I want to filter away the objects from the small list of the main list.
Please tell me if this is not clear.
My codes below:
NSArray *biglist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"smalllist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
for (NSString *listword in list);
NSMutableArray *wordlist = [[NSMutableArray alloc] init];
NSMutableArray *worindex = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
NSMutableDictionary *mutdic = [[NSMutableDictionary alloc] init];
NSMutableArray *mutarray = [[NSMutableArray alloc] init];
for (NSString *s in mainlist)
{
NSRange ran = [s rangeOfString:listword];
if (ran.location !=NSNotFound)
{
//my codes here
}
}
EDIT:
I think I can solve this by writing
int i;
for (i = 0; i<[list count]; i++)
{
NSString *same = [list objectAtIndex:i];
NSLog (#"listword: %#", same);
}
But I am not sure where to place it, inside the for loop s in mainlist or outside.
EDIT: This for loop works inside the main for loop.
EDIT:
Tried these codes, but it doesnt work somehow..
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"small" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *mainlist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSMutableArray *large = [NSMutableArray arrayWithArray:mainlist];
NSArray *newlarge;
for (NSString *listword in list)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(SELF beginswith[c] %#)",listword];
newlarge = [large filteredArrayUsingPredicate:predicate];
}
NSLog (#"large: %#", newlarge);
NSLog (#"finished!");
"I want to filter away the objects from the small list of the main list."
If I understand correctly, you want to remove an array of items from another array. You don't want to do that much work and allocations inside an n^2 loop.
This removes an array of items from another array. Depending on how large your array is you may need to optimize further but this works:
NSArray *small = [NSArray arrayWithObjects:#"three", #"two", nil];
NSMutableArray *large = [NSMutableArray arrayWithObjects:#"one", #"two", #"three", #"four", nil];
[large removeObjectsInArray:small];
// print
for (NSString *current in large)
{
NSLog(#"item: %#", current);
}
This outputs:
2011-10-13 08:39:21.176 Craplet[5235:707] item: one
2011-10-13 08:39:21.178 Craplet[5235:707] item: four
I figured it out by myself and solved this :)
It works almost perfectly.
My codes:
NSArray *big = [[NSArray alloc] initWithObjects:#"hello ->mache", #"heisann hoppsann ->hiya", #"nei men ->da", #"however ->what", #"may ->april", #"mai ->maj", nil];
NSArray *small = [[NSArray alloc] initWithObjects: #"heisann ", #"nei men ", #"however ", #"mai", nil];
NSMutableArray *smallwithh = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
for (NSString *same in small)
{
NSLog (#"listword: %#", same);
for (NSString *s in big)
{
NSRange ran = [s rangeOfString:same];
if (ran.location !=NSNotFound)
{
[smallwithh addObject:s];
NSUInteger ind = [big indexOfObject:s];
[mindexes addIndex:ind];
}
}
}
NSLog (#"smallwith: %#", smallwithh);
[smallwithh release];
NSMutableArray *newWords =[NSMutableArray arrayWithArray: big];
[newWords removeObjectsAtIndexes: mindexes];
[big release];
[small release];
NSLog (#"newWords: %#", newWords);