Exception with NSmutableArray of NSArrays - objective-c

I'm trying to do a list of lists... but when I use [listaCidades count] ...i'm getting throwing exception (sorry for long question but I mean that all this method is relevant for the question)
-(void) preencherCidades {
for (int iCnt = 0; iCnt < [listaEstados count]; iCnt++) {
NSString *estado = [listaEstados objectAtIndex:iCnt];
NSArray *listaNomeCidades = nil;
NSMutableArray *_listaCidades = [[NSMutableArray alloc]init];
NSString *path = [[NSBundle mainBundle] pathForResource:estado ofType:#"txt"];
NSString *file = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
listaNomeCidades = [[file componentsSeparatedByString:#"\n"]retain];
for (int iCnt2 = 0; iCnt2 < [listaNomeCidades count]; iCnt2++) {
NSArray *listaNomesPrefeitos = nil;
NSArray *listaPartidosPrefeitos = nil;
NSArray *listaVereadores = nil;
NSString *pathNomePrefeitos = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"prefeito-nome-%#",[listaNomeCidades objectAtIndex:iCnt2]] ofType:#"txt"];
NSString *fileNomePrefeitos = [NSString stringWithContentsOfFile:pathNomePrefeitos encoding:NSUTF8StringEncoding error:NULL];
listaNomesPrefeitos = [[fileNomePrefeitos componentsSeparatedByString:#"\n"]retain];
NSString *pathPartidoPrefeitos = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"prefeito-partido-%#",[listaNomeCidades objectAtIndex:iCnt2]] ofType:#"txt"];
NSString *filePartidoPrefeitos = [NSString stringWithContentsOfFile:pathPartidoPrefeitos encoding:NSUTF8StringEncoding error:NULL];
listaPartidosPrefeitos = [[filePartidoPrefeitos componentsSeparatedByString:#"\n"]retain];
NSString *pathVereadores = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"vereadores-%#",[listaNomeCidades objectAtIndex:iCnt2]] ofType:#"txt"];
NSString *fileVereadores = [NSString stringWithContentsOfFile:pathVereadores encoding:NSUTF8StringEncoding error:NULL];
listaVereadores = [[fileVereadores componentsSeparatedByString:#"\n"]retain];
Prefeito *prefeito = nil;
if([listaNomesPrefeitos count] > 0 && [listaPartidosPrefeitos count]>0)
prefeito = [[Prefeito alloc]initWithNome:[listaNomesPrefeitos objectAtIndex:0] partido:[listaPartidosPrefeitos objectAtIndex:0] id:iCnt2];
Cidade *cidade = [[Cidade alloc]initWithNome:[listaNomeCidades objectAtIndex:iCnt2] prefeito:prefeito listaVereadores:listaVereadores id:iCnt2];
[_listaCidades addObject:cidade];
}
[listaCidades addObject:_listaCidades];
}
}

By looking at your answer [Cidade isEqualToString:]:unrecognized selector to instance 0x1cec00. I came to know that that is the only point where string is expected but you are returning Object.
Its good that you solve the issue. Happy Coding.

I solved this with
NSMutableArray *listaCidades2 = (NSMutableArray *)[listaCidades objectAtIndex:indiceEstado];
Cidade *cidade = (Cidade *)[listaCidades2 objectAtIndex:row];
return cidade.nome;
instead of:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSMutableArray *listaCidades2 = (NSMutableArray *)[listaCidades objectAtIndex:indiceEstado];
return [listaCidades2 objectAtIndex:row];
}

Related

Error : -[NSURL rangeOfString:]: unrecognized selector sent to instance 0x6180000a0de0

I need help identifying my error. Does anyone know why it errors?
if (result == NSFileHandlingPanelOKButton) {
NSString *filePath = [[openPanel URLs] objectAtIndex:0];
NSLog(#"%#", filePath);
*CODE WORKS UP TO HERE*
NSString *strTemp = [self extractString:filePath toLookFor:#"//" skipForwardX:2 toStopBefore:#".png"];
NSLog(#"%#",strTemp);
NSString *copyScript = [NSString stringWithFormat:#"%# /tmp/%#.png", strTemp, myString];
strTemp = [[NSString alloc] init];
NSString *path = #"/Applications/APP.app/Contents/Resources/copy.sh";
NSArray *args = [NSArray arrayWithObjects:copyScript, nil];
[[NSTask launchedTaskWithLaunchPath:path arguments:args] waitUntilExit];
NSString* linkName = #"/tmp/";
NSString* extension = #".png";
NSString* fullPath = [NSString stringWithFormat:#"%#%#%#", linkName, myString, extension];
urlPathOfFile = [NSString stringWithFormat:#"URL/%#%#", myString, extension];
fileURL = [NSURL URLWithString:fullPath];
action = upload;
[self runAction];
Is it a memory error because I have too many strings?
There's a high probability that filePath points to a NSURL object, not NSString.

Saving to plist file issue

I can't save my new data to plist file for some reason. This is code I have been using for saving data:
-(void)saveData:(NSMutableDictionary *)dictionaryData toFile:(NSString *)filename {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *path = [docDir stringByAppendingPathComponent:filename];
NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:path];
[data addObject:dictionaryData];
[data writeToFile:filename atomically:YES];
}
this is code I used to copy file from bundle to app directory in case if it is not there :
-(NSMutableArray *)loadFromFile:(NSString *)filename {
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *path = [docDir stringByAppendingPathComponent:filename];
NSFileManager *fileMgr = [NSFileManager defaultManager];
if(![fileMgr fileExistsAtPath:path]) {
NSArray *fileArray = [filename componentsSeparatedByString:#"."];
NSString *name = [fileArray objectAtIndex:0];
NSString *ext = [fileArray objectAtIndex:1];
NSString *bundle = [[NSBundle mainBundle] pathForResource:name ofType:ext];
[fileMgr copyItemAtPath:bundle toPath:path error:&error];
}
NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:path];
return data;
}
For some reason I can't save new data to plist file. When I try to add new NSMutableDictionary object to my plist file (with saveData:toFile: method) and than reload my array variable with the plist file data - new object is not there. Am I doing something wrong?
this is how I load plist file :
#property (nonatomic, strong) NSMutableArray *modules;
#property (nonatomic, strong) NSMutableDictionary *module;
- (void)viewDidLoad {
[super viewDidLoad];
self.modules = [self loadFromFile:#"ModulesList.plist"];
self.module = [self.modules objectAtIndex:0];
for (int i = 0; i < self.modules.count; i++ ) {
NSLog(#"Modules array from plist file, module at index %i : %#",i, [self.modules objectAtIndex:i]);
}
than for testing purpose I have this code to add new module object:
- (IBAction)leftButton:(id)sender {
NSString *mytitle = [[NSString alloc] initWithFormat:#"my title"];
NSString *myauthor = [[NSString alloc] initWithFormat:#"my author2"];
NSUInteger myean = 22023423;
NSString *mytitle2 = [[NSString alloc] initWithFormat:#"my title 2"];
NSString *myauthor2 = [[NSString alloc] initWithFormat:#"my author2"];
NSUInteger myean2 = 29032432;
NSString *mytitle3 = [[NSString alloc] initWithFormat:#"my title 3"];
NSString *myauthor3 = [[NSString alloc] initWithFormat:#"my author 3"];
NSUInteger myean3 = 21023423;
NSMutableDictionary *mybook = [[NSMutableDictionary alloc] init];
NSMutableDictionary *mybook2 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *mybook3 = [[NSMutableDictionary alloc] init];
[mybook setObject:mytitle forKey:#"title"];
[mybook setObject:myauthor forKey:#"author"];
[mybook setObject:[NSNumber numberWithInteger:myean] forKey:#"ean"];
[mybook2 setObject:mytitle2 forKey:#"title"];
[mybook2 setObject:myauthor2 forKey:#"author"];
[mybook2 setObject:[NSNumber numberWithInteger:myean2] forKey:#"ean"];
[mybook3 setObject:mytitle3 forKey:#"title"];
[mybook3 setObject:myauthor3 forKey:#"author"];
[mybook3 setObject:[NSNumber numberWithInteger:myean3] forKey:#"ean"];
NSMutableArray *mybooks = [[NSMutableArray alloc] init];
[mybooks addObject:mybook];
[mybooks addObject:mybook2];
[mybooks addObject:mybook3];
[self.module setObject:mybooks forKey:#"books"];
[self.modules addObject:self.module];
for (int i = 0; i < self.modules.count; i++ ) {
NSLog(#"Modules array after add operation, module at index: %i: %#",i, [self.modules objectAtIndex:i]);
}
[self saveData:self.module toFile:#"ModulesList.plist"];
}
than when I will reload my self.modules array from plist with button action, my new data is not there:
- (IBAction)reload:(id)sender {
self.modules = [self loadFromFile:#"ModulesList.plist"];
for (int i = 0; i < self.modules.count; i++ ) {
NSLog(#"RELOAD: Modules array from plist file, module at index %i : %#",i,[self.modules objectAtIndex:i]);
}
}
this is screenshot of my plist file : http://dl.dropbox.com/u/49076351/Screen%20Shot%202013-02-27%20at%2016.27.45.png

NSArray BAD ACCESS

I'm trying to do a pickerView but I'm getting bad acess:
here is my code
-(void) viewWillAppear:(BOOL)animated {
list = [[NSArray alloc]init];
[self populateList]
}
-(void) populateList {
NSString *path = [[NSBundle mainBundle] pathForResource:#"nameoffile" ofType:#"txt"];
NSString *file = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
list = [file componentsSeparatedByString:#"\n"];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return (NSString *)[list objectAtIndex:row]; //here I'm getting bad acces
}
The error is: "Thread 1: EXC_BAD_ACCESS(code=1, address=0xa001cc65)"
NSArray returned by componentsSeparatedByString: is autoreleased value so you need to retain it.
You should remove:
list = [[NSArray alloc]init];
and add retain to:
list = [[file componentsSeparatedByString:#"\n"] retain];

Error on displaying NSArray objectAtIndex into UILabel

Despite many tries I have already done.. I am not getting to display correctly items from an NSArray into a UILabel..
When I NSLog the array the console returns me this:
2013-01-19 14:34:32.799 bloom[2766:c07] (
"0.877"
)
Which is the value I fetched from a website and parsed and etc..
The problem is that when I display it in a UILabel it shows me exactly the same thing and I need just the value without quotes to be displayed. Here's is how it is displaying:
Edit:
Here is my code:
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
for (NSDictionary *valuesDatum in _detailItem) {
NSDictionary *itemAtIndex = (NSDictionary *)_detailItem;
self.title = [itemAtIndex objectForKey:#"SYMBOL"];
NSString *strUrl = #"http://www.bloomberg.com/quote/";
NSString *ativo = [itemAtIndex objectForKey:#"SYMBOL"];
NSString *consulta = [strUrl stringByAppendingString:ativo];
NSURL *url = [NSURL URLWithString:consulta];
NSData *webData = [NSData dataWithContentsOfURL:url];
NSString *xPathQuery = #"//span[#class=' price'] | //span[#class=' trending_up up'] | //span[#class=' trending_up up']/span | //table[#class='snapshot_table']/tr/td";
TFHpple *parser = [TFHpple hppleWithData:webData isXML:NO];
NSArray *array = [parser searchWithXPathQuery:xPathQuery];
valores = [[NSMutableArray alloc]init];
for (TFHppleElement *element in array) {
[valores addObject:[[element firstChild] content]];
}
novosValores = [[NSMutableArray alloc]init];
for (NSString *valuesDatum in valores) {
NSString *removeNewLine = [[valuesDatum componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]] componentsJoinedByString:#" "];
NSString *removeSpace = [removeNewLine stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *removeSpaceOne = [removeSpace stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *trocaVirgulaPonto = [removeSpaceOne stringByReplacingOccurrencesOfString:#"," withString:#"."];
[novosValores addObject:trocaVirgulaPonto];
}
valoresFinais = [[NSMutableArray alloc]init];
for (NSString *valuesDatum in novosValores) {
NSArray *val = [valuesDatum componentsSeparatedByString:#" - "];
[valoresFinais addObject:val];
}
infos = [[NSMutableArray alloc]init];
for (NSArray *dados in valoresFinais) {
NSArray *arrayDados = [[NSArray alloc]initWithArray:dados];
for (NSString *teste in arrayDados) {
NSArray *arrayTeste = [teste componentsSeparatedByString:#","];
[infos addObject:arrayTeste];
}
}
NSLog(#"%#",[infos objectAtIndex:0]);
NSString *fff = [[NSString alloc] initWithFormat:#"%#", [infos objectAtIndex:0]];
[_detailDescriptionLabel setText:fff];
}
}
}
NEW EDIT:
I have this array:
2013-01-19 15:43:05.055 bloom[3564:c07] (
"7.730",
"0.020",
"0.26%",
"7.750",
"7.650-7.800",
"2.333.100",
"7.710",
"3.730-8.810",
"+4.04%"
)
All I need is a new array with the data from lines 5 and 8 separated by the "-".
So anyone has a light??
Thanks!!!
I solved this question with the help of Anoop. I changed a bit his code and finally my code is like this:
for (NSDictionary *valuesDatum in _detailItem) {
NSDictionary *itemAtIndex = (NSDictionary *)_detailItem;
self.title = [itemAtIndex objectForKey:#"SYMBOL"];
NSString *strUrl = #"http://www.bloomberg.com/quote/";
NSString *ativo = [itemAtIndex objectForKey:#"SYMBOL"];
NSString *consulta = [strUrl stringByAppendingString:ativo];
NSURL *url = [NSURL URLWithString:consulta];
NSData *webData = [NSData dataWithContentsOfURL:url];
NSString *xPathQuery = #"//span[#class=' price'] | //span[#class=' trending_up up'] | //span[#class=' trending_up up']/span | //table[#class='snapshot_table']/tr/td";
TFHpple *parser = [TFHpple hppleWithData:webData isXML:NO];
NSArray *array = [parser searchWithXPathQuery:xPathQuery];
valores = [[NSMutableArray alloc]init];
for (TFHppleElement *element in array) {
[valores addObject:[[element firstChild] content]];
}
novosValores = [[NSMutableArray alloc]init];
for (NSString *valuesDatum in valores) {
NSString *removeNewLine = [[valuesDatum componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:#" "];
NSString *removeSpace = [removeNewLine stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *removeSpaceOne = [removeSpace stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *removeSpaceTwo = [removeSpaceOne stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *removeDash = [removeSpaceTwo stringByReplacingOccurrencesOfString:#" - " withString:#" "];
NSString *trocaVirgulaPonto = [removeDash stringByReplacingOccurrencesOfString:#"," withString:#"."];
[novosValores addObject:trocaVirgulaPonto];
}
NSString *fullString=[novosValores componentsJoinedByString:#"_"];
NSString *changeDash = [fullString stringByReplacingOccurrencesOfString:#"-" withString:#"_"];
finalArray=[changeDash componentsSeparatedByString:#"_"];
//NSLog(#"%#", finalArray);
}
NSString *str = [[NSString alloc]initWithFormat:#"%#",[finalArray objectAtIndex:10]];
[_detailDescriptionLabel setText:str];
Are you sure you make like this:
label.text = [array objectAtIndex:0];
instead of:
label.text = array;
(
"0.877"
)
The above is an array, and you are putting that array onto label.
You have to use someLabel.text=[thatArray objectAtIndex:0];
EDIT:
As per your requirement try this one: (not compiler checked)
NSString *fullString=[array componentsJoinedByString:#"+"];
NSArray *brokenString=[fullString componentsSeparatedByString:#"-"];
NSString *mainString=brokenString[1];
NSArray *finalArray=[mainString componentsSepartedByString:#"+"];

Correcting a plist with dictionaries

Plist is copyed to documents directory if it doesn't exist.
If it already exists, I want to use the "Name" key from NSDictionary in bundleArray to find the matching NSDictionary in documentsArray.
When the match is found, I want to check for changes in the strings and replace them if there is a change.
If a match is not found it means this dictionary must be added to documents plist.
This is my code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self managePlist];
return YES;
}
- (void)managePlist {
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"Objects.plist"];
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"Objects" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path]) {
[fileManager copyItemAtPath:bundle toPath:path error:&error];
} else {
NSArray *bundleArray = [[NSArray alloc] initWithContentsOfFile:bundle];
NSMutableArray *documentArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
BOOL updateDictionary = NO;
for(int i=0;i<bundleArray.count;i++) {
NSDictionary *bundleDict=[bundleArray objectAtIndex:i];
BOOL matchInDocuments = NO;
for(int ii=0;ii<documentArray.count;ii++)
{
NSMutableDictionary *documentDict = [documentArray objectAtIndex:ii];
NSString *bundleObjectName = [bundleDict valueForKey:#"Name"];
NSString *documentsObjectName = [documentDict valueForKey:#"Name"];
NSRange range = [documentsObjectName rangeOfString:bundleObjectName options:NSCaseInsensitiveSearch];
if (range.location != NSNotFound) {
matchInDocuments = YES;
}
if (matchInDocuments) {
if ([bundleDict objectForKey:#"District"] != [documentDict objectForKey:#"District"]) {
[documentDict setObject:[bundleDict objectForKey:#"District"] forKey:#"District"];
updateDictionary=YES;
}
}
else {
[documentArray addObject:bundleDict];
updateDictionary=YES;
}
}
}
if(updateDictionary){
[documentArray writeToFile:path atomically:YES];
}
}
}
If I run my app now I get this message: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
How can I fix this?
When this is fixed, do you think my code will work?
If not, I would be happy for some suggestions on how to do this. I have struggled for a while and really need to publish the update with the corrections! Thanks a lot for your help.
Presumably the documentDict is actually immutable. Even though you assign it to an NSMutableDictionary, this doesn't accurately describe the underlying data.
NSMutableDictionary *documentDict = [documentArray objectAtIndex:ii];
should be:
NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithDictionary:[documentArray objectAtIndex:ii]];
and wherever you edit the documentDict, add:
[documentArray replaceObjectAtIndex:ii withObject:documentDict];
When you read a plist from file, an immutable dictionary/array with immutable children is created, so your
  NSMutableDictionary *documentDict = [documentArray objectAtIndex:ii];
line is erfectively a lie - you don't have a mutable dictionary. To create a mutable object from a plist, have a look at CFPropertyListCreateWithData and specify kCFPropertyListMutableContainersAndLeaves as the mutability option.
This is my final and working code using the answer from James Webster. Thanks to H2CO3 as well for contribution.
- (void)managePlist {
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"Object.plist"];
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"Object" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:path]) {
[fileManager copyItemAtPath:bundle toPath:path error:&error];
}
else
{
NSArray *bundleArray = [[NSArray alloc] initWithContentsOfFile:bundle];
NSMutableArray *documentArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
BOOL updateDictionary = NO;
for(int i=0;i<bundleArray.count;i++) {
NSDictionary *bundleDict=[bundleArray objectAtIndex:i];
for(int ii=0;ii<documentArray.count;ii++)
{
NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithDictionary:[documentArray objectAtIndex:ii]];
NSString *bundleObjectName = [bundleDict valueForKey:#"Name"];
NSString *documentsObjectName = [documentDict valueForKey:#"Name"];
NSRange range = [documentsObjectName rangeOfString:bundleObjectName options:NSCaseInsensitiveSearch];
if (range.location != NSNotFound) {
NSString *districtString = [bundleDict objectForKey:#"District"];
if ([documentDict objectForKey:#"District"] != districtString) {
[documentDict setObject:districtString forKey:#"District"];
[documentArray replaceObjectAtIndex:ii withObject:documentDict];
updateDictionary=YES;
}
}
}
}
if(updateDictionary){
[documentArray writeToFile:path atomically:YES];
}
}
}