Dividing a string for NSDict KEY and VALUE

Discussion in 'iOS Programming' started by larswik, May 16, 2012.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    Hi, I am scratching my head here and looking for the right code. I am downloading a text file from my server. The string looks like this.

    It is a link to a file and a number that represents DATE HOUR MINUTE. I have a white space that separates the 2 in the string. I am looking at reading in the first part and have it be the key and the number be the value in an NSMUtableDictionary.

    I can use the NSScanner and scan to the white space. But then I need to scan the next part from the number (which is a string) to the newline \n. I have about 200 lines that I need to scan.

    Is there a better way to do this or is NSScanner the right tool for this job?
     
  2. ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #2
    I would personally use componentsSeparatedByString:
     
  3. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #3
    Thanks ChOas, I thought about it for a while and I found a solution with NSScanner and it worked. Here is the code I used. It would seem that the scanner remembers where it left off. I had it scan and it picked up where it left off. The only thing that I can not tell from the NSLog is that if it included the whitespace in the second string. From the result it looks like it scans up to but does not include the white space. I would assume the white space would be included in the next string which is the value. Here was the result.

    Code:
    -(NSMutableDictionary *)phpDictWithKeys:(NSArray *)theArray{
        NSString *forKey = nil;
        NSString *forValue = nil;
        NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init];
    
        for (int i = 0; i < theArray.count ; i++) {
            NSString *indexFromArray = [theArray objectAtIndex:i];
            //NSLog(@"The array String %@", indexFromArray);
            NSScanner *scanner = [NSScanner scannerWithString:indexFromArray];
            
            while (![scanner isAtEnd]) { 
          
                [scanner scanUpToString:@" " intoString: &forKey];
                [scanner scanUpToString:@"\n" intoString: &forValue];
    
                [myDict setValue:forValue forKey:forKey];
            }
        }
        NSLog(@"TheDict %@", myDict);
        
        return myDict;
    }
    
    
     
  4. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #4
    Is there any particular reason you're not just using componentsSeperatedByString? That'll automatically remove the separating string (the whitespace in this case) for you...
     
  5. ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #5
    Works too!

    My way:



    Code:
    -(NSMutableDictionary *)phpDictWithKeys:(NSArray *)theArray{
         NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init];
    
        for (NSString *line in theArray) {
          NSArray *comp =[line componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
          [myDict setValue:[comp objectAtIndex:1] forKey:[comp objectAtIndex:0]];
        }
        NSLog(@"TheDict %@", myDict);
        
        return myDict;
    }
    
    
    I have no clue which is more efficient though :D
     
  6. larswik, May 16, 2012
    Last edited: May 16, 2012

    larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #6
    There was no particular reason I did not use componentsSeperatedByString except for the fact I was not aware of it. NSScanner was something that I used in the past and knew I could read in line by line.

    But since I always want to learn new things to keep expanding I should try it. ChOas provided some code that I can look over and test. It is smaller then mine code and seems like a smarter way of doing it.

    Let me see if I get it.

    in the for loop you are creating a new NSString pointer for each index in the array that it needs to iterate through. Then you are creating a new array with a pointer called *comp. The next part is taking 'line' and scanning upto the white space which then stores it in the array. So basically if I had a string that was @"This is a string"; it would store each word in an index in the comp array?

    After that it adds them to the dict and it is done.

    It looks like that is what is happening?

    EDIT: I just rewrote it (did not copy paste, wanted it to sync in) it worked perfectly! Thanks for sharing that info, code looks cleaner!

    Thanks!
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
  8. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #8
    I wrote a little php script that is on my server that scans my files looking for mod dates. It then creates a txt file that I am downloading and parsing in the phone and looking for changes from the last txt file it saved as a plist in my Document directory as a plist.

    How would saving the .plist to my server help me?
     
  9. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #9
    If you have a plist on the server then you don't have to parse it in your app. Just download it and read it into a dictionary. Apple already wrote the parser.
     
  10. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #10
    Interesting... That might save a step or two. So would the server then create a plist that I would just download and loading to a dictionary on the phone?
     
  11. ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #11
    You are correct! The loop that's used is a 'Fast enumeration' loop. It is an easy way to go over the elements in an array or the keys in a dictionary.

    It is not as much scanning as just splitting the string in components (hence the comp name :) ) @"This is a string" would indeed result in an NSArray containing @"This", @"is", @"a", @"string". I am a Perl programmer and this seems more naturally to me than NSScanner because I know what I'm looking for beforehand. I use NSScanner when I'm not totally sure what imput I'm getting.

    Lastly, PD made a good point. You can store the info in a plist. That will give you a dictionaty instantly.
     
  12. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #12
    I guess how the plist is created is the question. I believe there is a tool that doesn't require Mac OS that will build a plist file and which could run on your server, but I don't remember its name. Obviously it would be simple to create a plist in code on a Mac. I'm pretty sure there is also a command line tool for editing plists that can run on a Mac also.

    Look up plistbuddy and a little googling should let you know what's out there.
     
  13. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #13
    Cool. Last night I finally finished updating my app to take advantage of the PHP script I wrote. Now the work load is off of my iphone checking the mod dates. It's only downloading a 14K txt file file with about 172 items.

    But I will look up buddylist. That sounds like another way to speed it up again. But when I test it last night it went from 45 seconds to check 172 items to 2 to 3 seconds to download and parse it.

    Much faster.

    Thanks guys!
     
  14. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #14
    I found this link on manipulating plists http://prowiki.isc.upenn.edu/wiki/Manipulating_Plists

    I know little about them even though I use them often. I wonder if I could just take my information and rebuild it as a plist. in the link above about 1/3 way down the page the give this example

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
    <plist version="1.0"> 
    <dict> 
         <key>doICrash</key> 
         <string>No</string> 
    </dict>
    
    </plist>
    
    The example used is a dict with a KEY and a STRING. I could manually build something like this in PHP and save it. But I am unsure if there is anything hidden behind the scene that the iPhone would look to as a valid plist file?
     
  15. ChOas, May 20, 2012
    Last edited: May 20, 2012

    ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #15
    As long as your file validates against the DTD you should be fine...
     
  16. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #16
    I'll read up on plists. The extent of what I know about them is how to write, read them.

    After thinking about it it would be fun to try but the most I would ever have is about 300 items at a time. Downloading a txt file and parsing it is pretty quick at this point.

    Thanks though!

    -Lars
     

Share This Page