Getting a variable string?

Discussion in 'iOS Programming' started by ELBdelorean, Jun 25, 2011.

  1. ELBdelorean macrumors member

    Joined:
    May 18, 2010
    #1
    Just as a disclaimer: I've been searching for the answer for this but I can't find it.

    I have a string of JSON text that I've managed to get a certain part of, but now I need to get another part of that. I have this string:

    Code:
    (
            {
            balance = "3201.32584";
        }
    )
    
    Where the number after balance varies. How would I take just that number as a string or even as a float?
     
  2. Sykte macrumors regular

    Joined:
    Aug 26, 2010
    #2
    Help me out with a few more details.... You have a string and you want to convert it to a float. What does your current string look like?
    1. balance = "3201.32584"
    2. 3201.32583
    3. everything you posted?
    4. or other.
     
  3. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #3
    The current string I have is everything posted in the code tags.
     
  4. Sykte macrumors regular

    Joined:
    Aug 26, 2010
    #4
    You could use NSScanner and set the characters to be skipped. "({balance=});

    You could also look at a JSON parser. I know JSONKit is very well liked.


    edit:
    http://cocoaobjects.com/?s=json
     
  5. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #5
    This is not valid JSON. If you really intended it to be JSON, you should make sure you are doing it correctly and then you might as well use one of the available JSON parsers like Sykte suggests.
     
  6. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #6
    I know it's not...that's a certain part of the JSON that I've already retrieved.
     
  7. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #7
    So that's a string value for one of the JSON keys?
     
  8. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #8
    Yep.
     
  9. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #9
    Gotcha. Do you have control over how this whole JSON text is being formatted? The obvious thing to do if you could is reformat that string so it's a valid piece of JSON itself and then you can just parse the value no problem.
     
  10. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #10
    Unfortunately, no. The JSON text is being retrieved from a GET: request.
     
  11. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #11
    Search the string for the first quote-mark.
    Search from that point for the next quote-mark.
    Take the substring between them.
    Parse the substring as a number (e.g. any NSDecimalNumber method that takes NSString arg).
    With a NSDecimalNumber object in hand, call appropriate method for desired return type.
     
  12. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #12
    I'm getting 'Thread 1: Program received signal: "SIGABRT".' from this:

    Code:
    NSString *theString = [object2 objectForKey:@"data"];
    NSLog(@"%@", theString);
    NSScanner *theScanner = [NSScanner scannerWithString:theString];
    NSLog(@"%@", theString);
    NSString *aString = [[theScanner string] substringFromIndex: [theScanner scanLocation]]; // error comes here
    NSLog(@"%@", aString);
    
    I'm not scanning it for anything yet; when I do, I receive the same error.
     
  13. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #13
    Post the output produced by the NSLog() statements.
     
  14. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #14
    Code:
    [__NSArrayI substringFromIndex:]: unrecognized selector sent to instance 0x26a1c0
    
    *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI substringFromIndex:]: unrecognized selector sent to instance 0x26a1c0'
    *** First throw call stack:
    (0x329e8d2f 0x3114b0e3 0x329eca45 0x329ebc23 0x32966d10 0x2b87 0xc9cb 0xe1df 0x368d9e49 0x368d972b 0x368d8f4d 0x368d96d3 0x368d97bb 0x368321c7 0x35e4e17d 0x35e4320b 0x35e43335 0x35e42e33 0x35ed8465 0x35e42d59 0x35e42cd1 0x329b30f5 0x329b4827 0x329b57b3 0x32953c43 0x32953b05 0x3433c27b 0x3433c311 0x33167127 0x331642a5 0x2669 0x2600)
     
  15. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #15
    Where's the output from the NSLog statements?

    The output from the NSLogs would provide some evidence that the statements leading up to the crash are actually being executed.

    All I see is a crash from sending substringFromIndex: to what appears to be an NSArray instance. Since NSArray doesn't have a substringFromIndex: method, the result is "unrecognized selector sent to instance 0x26a1c0".

    Since a typical reason for "unrecognized selector sent to xxx" is a memory management error, what leads up to the crash is very important. None of the posted code should cause a memory management error, neither under-retain nor over-release nor failure to retain an autoreleased object.

    So the jist of my question is "What's your evidence that the substringFromIndex: in the crash is actually the one in the posted code?". Or another way of looking at it is "How do you know it's not some OTHER substringFromIndex: causing the crash?". The strongest evidence would be a stack-trace from the crash, which I think you can get in the debugger. Are you even using the debugger?

    Have you run the code using Instruments with zombies enabled?
     
  16. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #16
    Right, sorry. I was kind of in a hurry and I posted the wrong thing.

    Code:
     (
            {
            balance = "1029.20387";
        }
    )
    
    
     (
            {
            balance = "1029.20387";
        }
    )
     
  17. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #17
    So is the "unrecognized selector" error from the SIGABRT crash or not?

    If you take this code:
    Code:
    NSString *aString = [[theScanner string] substringFromIndex: [theScanner scanLocation]]; // error comes here
    
    and break it down, NSLog'ing each independent value, what is the output?

    By "break it down" I mean like this:
    Code:
    NSUInteger index = [theScanner scanLocation];
    ## NSLog the index value here ##
    NSString * str = [theScanner string];
    ## NSLog the str value here ##
    NSString * substr = [str substringFromIndex:index];
    ## NSLog the substr value here ##
    
    And assuming you're not using the debugger, now might be a good time to learn it. You won't get very far without it.
     
  18. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #18
    Yes.

    I get the SIGABRT error at this line now:
    Code:
    NSUInteger index = [theScanner scanLocation];
    NSLog(@"%i", index);
    NSString * str = [theScanner string];
    NSLog(@"%@", str);
    NSString * substr = [str substringFromIndex:index];       // error comes here
    NSLog(@"%@", substr);
    
     
  19. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #19
    Uh hu. So what are the NSLog outputs? The point of them being there is to aid you (and us) in debugging. Without them we are just guessing.
     
  20. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #20
    The error:
    Code:
    [__NSArrayI substringFromIndex:]: unrecognized selector sent to instance 0x266a60
    
    
     *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI substringFromIndex:]: unrecognized selector sent to instance 0x266a60'
    *** First throw call stack:
    (0x329e8d2f 0x3114b0e3 0x329eca45 0x329ebc23 0x32966d10 0x2b79 0xc9bf 0xe1d3 0x368d9e49 0x368d972b 0x368d8f4d 0x368d96d3 0x368d97bb 0x368321c7 0x35e4e17d 0x35e4320b 0x35e43335 0x35e42e33 0x35ed8465 0x35e42d59 0x35e42cd1 0x329b30f5 0x329b4827 0x329b57b3 0x32953c43 0x32953b05 0x3433c27b 0x3433c311 0x33167127 0x331642a5 0x2681 0x2618)
    
    NSLog:

    Code:
     0
    
     (
            {
            balance = "1029.20387";
        }
    )
     
  21. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
  22. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #22
    Based on this information, I suspect the following code is making a deeply flawed assumption:
    Code:
    NSString *theString = [object2 objectForKey:@"data"];
    
    I don't think it's returning an NSString at all. I think it's returning an NSArray.

    When used with the %@ print format, an NSArray will show a list of its values enclosed in parentheses. Exactly as shown.

    Furthermore, I suspect there's one element in the NSArray, and it's an NSDictionary. Because an NSDictionary will print its key/value pairs enclosed in { }s. Exactly as shown.

    Within that NSDictionary, there is a single key "balance", whose value is a string "1029.20387" (type NSString*). I can tell it's a string because it's quoted. If it were an NSNumber, it wouldn't be quoted.

    FWIW, I suspect [NSScanner scannerWithString:theString] doesn't fail only because scannerWithString: doesn't actually do anything with its argument until later.


    So I think you need to explain how object2 gets its value.

    You should also look at some of the NSObject methods that return the class of an object, and work out some way to identify what type is being used at each relevant point in the assignment of a value to object2.
     
  23. ELBdelorean thread starter macrumors member

    Joined:
    May 18, 2010
    #23
    You're right. For some reason, theString is of type NSArray. object2 is an NSDictionary with JSON data retrieved from a JSON parser. Is there any reason why theString is returning an NSArray?
     
  24. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #24
    Probably because the JSON parser is doing its job. That's what a JSON parser does: it parses the JSON text and converts it into nested dictionary, array, name/value pairs, etc.

    http://json.org/
     

Share This Page