Obj-C, encode Simplified Chinese in an iTunes search querystring? - objective-c

I'm struggling to use the iTunes search API with Simplified Chinese. I've tried a couple of character variations (provided by google translate) along with HTML encoding the characters.
The code below doesn't cause any errors but it doesn't give me any results, unlike English words. I've also tried different Chinese words.
However I'm not sure how to proceed.
NSString *url_string = #"";
NSString *keyword = [#"Chéngfǎ" stringByReplacingOccurrencesOfString: #" "
withString: #"%20"];
//NSString *keyword = [#"乘法" stringByReplacingOccurrencesOfString: #" "
withString: #"%20"];
url_string = [NSString stringWithFormat:
#"https://itunes.apple.com/search?term=%#&country=%#&entity=software", keyword, #"cn"];
NSError *error;
NSData *data = [NSData dataWithContentsOfURL: [NSURL URLWithString: url_string]];
NSMutableArray *json;
if (data != nil)
{
json = [NSJSONSerialization JSONObjectWithData:data options: kNilOptions error: &error];
}
NSDictionary *outer = [json valueForKey: #"results"];
for(NSDictionary *item in outer)
{
//results
}

I tried to type the URL into browser and I get the results. I think you need to percent encode the chinese characters?
https://itunes.apple.com/search?term=%E4%B9%98%E6%B3%95&country=cn&entity=software
You can use iOS function stringByAddingPercentEncodingWithAllowedCharacters.

Related

Remove first line in JSON response

I am using the Google Speech API unofficially. If you send it an audio file saying "Test", it will respond with this:
{"result":[]}
{"result":[{"alternative":[{"transcript":"test","confidence":0.88845605},{"transcript":"tests"},{"transcript":"the test"},{"transcript":"text"},{"transcript":"Test"}],"final":true}],"result_index":0}
I need to remove the first line of this response so my parser will not error out.
Is there an official way to remove this first line in the JSON?
I am using Xcode 6.1 (I haven't updated Xcode yet) with the iOS 6.1 SDK.
// Assuming your string looks something like this
NSString *fileContents = #"Bob Smith: 1 (234)-567-8901\nBob Smith: bob#bob.com";
// Lets store the information on each new line in an array
NSArray *lines = [fileContents componentsSeparatedByString:#"\n"];
// The second object will contain the email
NSString *email = [lines objectAtIndex:1];
NSLog(#"%#",email);
NSString* fileRoot = [[NSBundle mainBundle]
pathForResource:#"test" ofType:#"txt"];
NSString* fileContents = [NSString stringWithContentsOfFile:fileRoot
encoding:NSUTF8StringEncoding error:nil];
NSArray* allLinedStrings = [fileContents componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
In this array you can judge if it contains a phoneNumber, str is every element.
NSString *phoneNumber = [str componentsSeparatedByString:#":"][1];
if phoneNumber is a phoneNumber format. Then delete this line.

How to convert NSData which contains a line break to a NSString

The following code works perfectly to convert the NSData that I got from a URL/JSON file to a NSString, EXCEPTION MADE by the cases that data contains line breaks!
What's wrong with my code?
My Code:
NSError *errorColetar = nil;
NSURL *aColetarUrl = [[NSURL alloc]initWithString:#"http://marcosdegni.com.br/petsistema/teste/aColetar3.php"];
NSString *aColetarString = [NSString stringWithContentsOfURL:aColetarUrl encoding:NSUTF8StringEncoding error:&errorColetar];
NSLog(#"NSString: %#", aColetarString);
if (!errorColetar) {
NSData *aColetarData = [aColetarString dataUsingEncoding:NSUTF8StringEncoding];
self.arrayAColetar = [NSJSONSerialization JSONObjectWithData:aColetarData options:kNilOptions error:nil];
}
NSLog(#"arrayAColetar %#", self.arrayAColetar);
Log Results:
**NSString**: [{"id_atendimento":"2","observacoes":"ABC-Enter-->
DEF-Enter-->
GFH-END"},{"id_atendimento":"1","observacoes":"123Enter-->
345Enter-->
678End"}]
**arrayAColetar** (null)
As you can see my bottom line is an empty array :(
Thanks in advance!
By checking the error message hidden under 'error:nil' I found a "Unescaped control character around character" issue and implemented the code below from Unescaped control characters in NSJSONSerialization
and got a new 'cleaned' string.
- (NSString *)stringByRemovingControlCharacters: (NSString *)inputString {
NSCharacterSet *controlChars = [NSCharacterSet controlCharacterSet];
NSRange range = [inputString rangeOfCharacterFromSet:controlChars];
if (range.location != NSNotFound) {
NSMutableString *mutable = [NSMutableString stringWithString:inputString];
while (range.location != NSNotFound) {
[mutable deleteCharactersInRange:range];
range = [mutable rangeOfCharacterFromSet:controlChars];
}
return mutable;
}
return inputString;
}

Best way to parse a JSONP response

I am calling an API, which should return a JSON file. Here is the API link: http://sg.media-imdb.com/suggests/h/hello.json
The problem is: this JSON file has something wrapping the JSON response
imdb$hello(JSON)
So the best approch that I can see is to use a regex expression to extract only what I need. Something like: ~/\((.*)\)/.
However I would like to use the new JSON iOS5 API, which (as far as i know) only accepts NSData as input. So, I don't want to convert my response from NSData to NSString, parse that using regex, and put that in another NSData object.
Can anyone see a better/cleaner solution for that JSON parsing?
What you have isn't JSON, but JSONP. If you're not in JavaScript, I believe the correct way to handle is just as you say, preprocess and then parse.
NSError *jsonError = nil;
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSRange range = [jsonString rangeOfString:#"("];
range.location++;
range.length = [jsonString length] - range.location - 1;
jsonString = [jsonString substringWithRange:range ];
NSJSONSerialization *jsonResponse =
[NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]
options:0
error:&jsonError];
Why don't you just do something like this before parsing the JSON?
response = [response stringByReplacingOccurrencesOfString:#"imdb$hello" withString:#""];
How regular is this string. It will always be there?
// Remove #"imdb$hello(" and #")" that wraps the response string.
NSRange JSONRange = NSMakeRange(11, [responseString length] - 12);
NSString *JSONString = [responseString substringWithRange:JSONRange];
// Now you can parse as normal…
You will need to craft the method of peeling away the wrapper with your own level of certainty.

Pulling Data From JSON

I have a simple JSON string that looks like
(
{
ID = 1;
response = Yes;
}
)
And my NSDictionary is not pulling the objectForKey. The jsonArray is displaying correctly. My code:
hostStr = [[hostStr stringByAppendingString:post] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *hostURL = [NSURL URLWithString:hostStr];
NSString *jsonString = [[NSString alloc] initWithContentsOfURL:hostURL];
self.jsonArray = [jsonString JSONValue];
[jsonString release];
NSLog(#"%#", jsonArray);
NSDictionary *infoDictionary = [self.jsonArray objectForKey:#"ID"];
NSLog(infoDictionary);
This is probably the case since you have completely invalid JSON (test it out at http://jsonlint.com/). Because you are missing the quotation marks in your JSON the elements won't match the id ID. All object names/keys need to be in quotation marks.
You're lucky that your framework interprets your invalid JSON (somehow) correctly so that you actually get an array or a dictionary. Because of this the result of NSLog will be correct.
Rewrite your JSON like this to get it working:
{
"ID": 1,
"response": "YES"
}
(Also be sure that jsonArray is a NSDictionary)

Parsed TouchXML XML file crashes when reading NSString

I'm able to successfully parse the contents of a XML file using TouchXML, but when I try to read an individual NSString, from the NSMutableArray that stores the parsed content, the iPhone app crashes.
My NSLog shows me that the file has been parse as it should, giving this output:
(
{
href = "mms://a19349.l412964549958.c41245496.f.lm.akamaistream.net/D/194359/4125596/v0001/reflector:49944";
},
{
href = "mms://a4322.l4129624350471.c414645296.a.lm.akamaistream.net/D/473432/4129566/v0001/reflector:546441";
} )
Here is the code I'm using to do the parsing:
NSMutableArray *res = [[NSMutableArray alloc] init];
.... Parsing happens here ....
Then I try to retrieve the string from the NSMutableArray, using this code (and the app crashes when trying to read this line of code, posted below NSMutableString *string1 = [NSMutableString stringWithString:url];
NSString *url = [[NSString alloc] init];
url = [res objectAtIndex:0];
NSMutableString *string1 = [NSMutableString stringWithString:url];
[string1 deleteCharactersInRange: [string1 rangeOfString: #"href = "]];
[string1 deleteCharactersInRange: [string1 rangeOfString: #";"]];
NSLog(#"Clean URL: %#", string1);
Please, how can I solve this problem? Thank you!
TouchXML returns you an array of NSDictionaries. In order to extract string you need to take value from this NSDictionary:
NSString *url = [[res objectAtIndex:0] objectForKey:#"href"];