1

How do I parse an HTML response in Objective-C, to find a JSON object embedded in the HTML.

here is the response I'm getting...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1"><title>
<script src="/Scripts/LocalLogin_vv1CC4D69C143F4D6.js" type="text/javascript"></script>
<script type="text/javascript">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<meta http-equiv=X-UA-Compatible content=IE=EmulateIE7 />
<title></title>

<script type="text/javascript" language="javascript">


FRAME_API = new FrameApi({
userId: '2269113',
proxyUserId: '2269113',
isProxy: false,
username: 'inst1',
enrollments: [{id: '2366888', userId: '2269113'}],

viewAda: false,

// Strings
I18N : {
    ItemViewerFrame: 'Item Viewer Frame',
    ItemEditorFrame: 'Item Editor Frame',
    GroupSetupFrame: 'Group Setup Frame',
    notLoggedIn: 'You are no longer logged in.\<br /\>Please click {0} now.',
    notConnected: 'You have been disconnected.\<br /\>Please connect and click {0}.',
    login: 'Login'
}
});
Ext.onReady(function() {
if (typeof (Ext.QuickTips) != 'undefined') {
    Ext.QuickTips.init();
}
var parentApi = FRAME_API.findParentApi(window);
if(parentApi != null) {
    FRAME_API = parentApi;
}
else {
    FRAME_API.init(15);
}
});
</script>
</head>
</body>
</html>

Now, how in the world do I get a hold of the:

enrollments: [{id: '2366888', userId: '2269113'}]

and make it a json object so I can retrieve the userId?

PS: I already have the response stored in a NSString object....

Thanks in advance!!!


So, I tried the following:

NSString* regexString =@"enrollments: \[.*?\],";
NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
NSError* regExerror = NULL;

NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:regexString options:options error:&regExerror];
if (regExerror) {
    NSLog(@"%@", [regExerror description]);
}

    //store the response from the server - HTML FORMAT
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];


NSString* loginResponse = [[[NSString alloc] initWithData:data encoding: NSASCIIStringEncoding] autorelease];

NSArray* results = [regex matchesInString:loginResponse options:0 range:NSMakeRange(0, [loginResponse length])];
for (NSTextCheckingResult* result in results) {

    NSString* resultString = [loginResponse substringWithRange:result.range];
    NSLog(@"%@",resultString);
}

But nothing gets store in the a array... I tested the regex at a few online testers with different portions of the response and it works fine... this is my first time using regex in general. I already looked in the class reference and it seems like it "SHOULD" work...

Any ideas? THANKS!!! :D

Tim Post
  • 33,371
  • 15
  • 110
  • 174
Johan
  • 75
  • 1
  • 7

2 Answers2

4

If you're not targeting iOS4+, you can use NSScanner. Depending on how reliably that page is rendered, you could use something like

NSScanner* scanner = [NSScanner scannerWithString:yourStringHere];
NSString* targetString; //your JSON ends up here
[scanner scanUpToString:@"enrollments: " intoString:NULL];
[scanner scanUpToString:@"\n" intoString:&targetString];

However, if you're okay with targeting iOS4+, I'd strongly agree with j0k that NSRegularExpression is the way to go. If you're not familiar with regular expressions, the pattern I'd suggest is something like @"enrollments: \[.*?\]," to match the whole string, or if it's super reliably looking like that (ie, always an array with one object with those exact properties, you could try @"enrollments: [{id: '(\d+?)', userId: '(\d+?)'}]".

On the other hand, the first one is more flexible and you can easily use something like Nextive JSON to parse it.

Morgan Harris
  • 2,589
  • 14
  • 17
  • Yeah, I'm targeting iOS4+... I'll try the regular expression solution... I'm not realy familiar with regular expression because I've never had to use them before, so thanks for the example... Now, why would you go for regular expression on iOS4+ and not NSScaner? No support for regex before iOS4? THANKS! :) – Johan Aug 02 '11 at 13:26
2

If you're developing for iOS4+ and you're looking for the same pattern every time, I'd look into using a NSRegularExpression.

csano
  • 13,266
  • 2
  • 28
  • 45
  • Thanks for the tip... I was hopping there was a different solution out there, other than regular expressions... :) I'll look into it and let you all know, once I have a chance to get on it tonight... PS: I'M TARGETING iOS4+... – Johan Aug 02 '11 at 13:19