Dealing with NSDictionary content parsed from Flickr - objective-c

I'm having an issue properly accessing an NSDictionary built from Flickr data (the flickr.photosets.getPhotos call). Instead of just showing the content of a description tag, it reads the description tag… along with some unnecessary data and quotes.
For example:
NSLog (#"Item description readout: %#", itemDescriptionPre);
yields this response:
Item description readout: {
"_content" = "This is a caption from a photo drawn through Flickr";
}
I've tried to modify the NSString with this
NSString *descripTruncated = [itemDescriptionPre substringFromIndex:17];
But it didn't causes a crash at runtime. It also doesn't address the items at the end of the item. I apologize since NSString modifications seem to be talked about a lot here, but I couldn't find circumstances that mirror mine.
Here is some more context to my code:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Storing incoming data");
NSDictionary *results = [jsonString JSONValue];
NSLog(#"Building NSDictionary.");
NSArray *photos = [[results objectForKey:#"photoset"] objectForKey:#"photo"];
NSLog(#"Building array from dictionary.");
// Loop through each entry in the dictionary...
for (NSDictionary *photo in photos)
{
NSString *title = [photo objectForKey:#"title"];
NSString *description = [photo objectForKey:#"description"];
[photoTitles addObject:title];
[photoDescriptions addObject:description];
}
NSLog(#"Nicer display for results: %# First image title: %# First image description: %#", results, [photoTitles objectAtIndex:0], [photoDescriptions objectAtIndex:0]);
[self updateDisplay];
}
-(void) updateDisplay{
NSString *capTitle = [[photoTitles objectAtIndex:0] uppercaseString];
photoTitleDisplay.text = capTitle;
NSString *itemDescriptionPre = [photoDescriptions objectAtIndex:0];
NSLog (#"Item description readout: %#", itemDescriptionPre);
}

itemDescriptionPre is actually an NSDictionary. This should work:
NSDictionary *itemDescriptionPre = [photoDescriptions objectAtIndex:0];
NSString *itemDescription = [itemDescriptionPre objectForKey:#"_content"];

Related

how to convert an array into string? [duplicate]

In my iPhone aplication I have a list of custom objects. I need to create a json string from them. How I can implement this with SBJSON or iPhone sdk?
NSArray* eventsForUpload = [app.dataService.coreDataHelper fetchInstancesOf:#"Event" where:#"isForUpload" is:[NSNumber numberWithBool:YES]];
SBJsonWriter *writer = [[SBJsonWriter alloc] init];
NSString *actionLinksStr = [writer stringWithObject:eventsForUpload];
and i get empty result.
This process is really simple now, you don't have to use external libraries,
Do it this way, (iOS 5 & above)
NSArray *myArray;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myArray options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
I love my categories so I do this kind of thing as follows
#implementation NSArray (Extensions)
- (NSString*)json
{
NSString* json = nil;
NSError* error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:&error];
json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return (error ? nil : json);
}
#end
Although the highest voted answer is valid for an array of dictionaries or other serializable objects, it's not valid for custom objects.
Here is the thing, you'll need to loop through your array and get the dictionary representation of each object and add it to a new array to be serialized.
NSString *offersJSONString = #"";
if(offers)
{
NSMutableArray *offersJSONArray = [NSMutableArray array];
for (Offer *offer in offers)
{
[offersJSONArray addObject:[offer dictionaryRepresentation]];
}
NSData *offersJSONData = [NSJSONSerialization dataWithJSONObject:offersJSONArray options:NSJSONWritingPrettyPrinted error:&error];
offersJSONString = [[NSString alloc] initWithData:offersJSONData encoding:NSUTF8StringEncoding] ;
}
As for the dictionaryRepresentation method in the Offer class:
- (NSDictionary *)dictionaryRepresentation
{
NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
[mutableDict setValue:self.title forKey:#"title"];
return [NSDictionary dictionaryWithDictionary:mutableDict];
}
Try like this Swift 2.3
let consArray = [1,2,3,4,5,6]
var jsonString : String = ""
do
{
if let postData : NSData = try NSJSONSerialization.dataWithJSONObject(consArray, options: NSJSONWritingOptions.PrettyPrinted)
{
jsonString = NSString(data: postData, encoding: NSUTF8StringEncoding)! as String
}
}
catch
{
print(error)
}
Try like this,
- (NSString *)JSONRepresentation {
SBJsonWriter *jsonWriter = [SBJsonWriter new];
NSString *json = [jsonWriter stringWithObject:self];
if (!json)
[jsonWriter release];
return json;
}
then call this like,
NSString *jsonString = [array JSONRepresentation];
Hope it will helps you...
I'm a bit late to this party, but you can serialise an array of custom objects by implementing the -proxyForJson method in your custom objects. (Or in a category on your custom objects.)
For an example.

To see more than pointers in an array (objective C)

If i enumerate an array i get
<myArray: 0x71b26b0>
<myArray: 0x71b2830>
<myArray: 0x71b2900>
I could take it that myData is behind the pointers listed, but if I wanted to explicitly see (log) the contents at each address, how to do that?
I have tried the &myData to no avail
--
for the benefit of uchuugaka:
-(void)loadObservedItems{
NSString *path = [self observationFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
myArray = [unarchiver decodeObjectForKey:#"ObserveKey"];
[unarchiver finishDecoding];
} else {
myArray = [[NSMutableArray alloc] initWithCapacity:10];
}
NSLog(#" %#",myArray);
}
Add to MyClass.m:
-(NSString*)description {
NSMutableDictionary* descDict = [NSMutableDictionary dictionary];
[descDict addObject:someField forKey:#"someField"]
[descDict addObject:anotherField forKey:#"anotherField"];
[descDict addObject:yetAnotherField forKey:#"yetAnotherField"];
return [descDict description];
}
Then just use NSLog(#"myObject is %#", myObject);. Just like the big guys.
Slightly more sophisticated is to (within the method) pre-pend your class name and the object address to the result string, but that's usually unnecessary for simple debugging.
But I think you can do that like this:
return [NSString stringWithFormat:#"%# : %#", [super description], [descDict description]];

iPhone get data from plist

English is not my native language; please excuse typing errors.
I have read similar questions but I couldn't find anything that could solve my problem..
I am making an iPhone app that shows a list of notes in a table view, and user can add and delete note.
When I add a new note to a server, I get a plist which looks like this:
<plist>
<dict>
<key>success</key><true />
<key>note</key><string>new note</string>
</dict>
</plist>
After user taps the add button, I request a connection to the server, and I do,
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[resultData appendData:data];
}
and then
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSError *sendError;
NSArray *result = [NSPropertyListSerialization propertyListWithData:resultData options: NSPropertyListMutableContainersAndLeaves format:NULL error:&sendError];
if([result count] > 0){
for(NSDictionary *dict in result){
for(NSDictionary *dict in result){
// This gives me an error "objectForKey: unrecognized selector to instance"
NSLog(#"%#", [dict objectForKey:#"success"]);
}
}
}
}
I thought that dict may not be a dictionary, so I tried NSLog(#"%#", dict); and it shows just success. But, I still don't know how I can get the value of success.
Try this ::
.h File
#property (nonatomic,retain) NSDictionary *dict;
.m file
NSString *errorDesc = nil;
NSPropertyListFormat format;
NSString *rootPath;
rootPath = [[NSBundle mainBundle] pathForResource:#"FILE_NAME"
ofType:#"plist"];
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:rootPath];
dict = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
//NSLog(#"PLIST retrive:%#",plistXML);
if (!dictLang) {
NSLog(#"Error reading plist: %#, format: %d", errorDesc, format);
}
Get Value ::
NSLog(#" Success :: %#", [dict objectForKey:#"success"]);
Hope, it'll help you.
Thanks.
if ([[NSPropertyListSerialization propertyListWithData:resultData options: NSPropertyListMutableContainersAndLeaves format:NULL error:nil] isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *tempDicts = [NSPropertyListSerialization propertyListWithData:nil options: NSPropertyListMutableContainersAndLeaves format:NULL error:nil];
}
else if ([[NSPropertyListSerialization propertyListWithData:resultData options: NSPropertyListMutableContainersAndLeaves format:NULL error:nil] isKindOfClass:[NSArray class]])
{
NSMutableArray *tempDicts = [NSPropertyListSerialization propertyListWithData:nil options: NSPropertyListMutableContainersAndLeaves format:NULL error:nil];
}
The return value of the method on NSPropertyListSerialization is - quite logically - the root object of the property list you receive. So result is an NSDictionary (I can't even imagine why you assume it's an array...!?). Try this:
NSLog(#"%#", [result objectForKey:#"success"]);

Strange NSData Output

I have some unexpected results coming from the following code:
- (NSData *)postDataWithDict:(NSDictionary *)postDict
{
// Assume key is urlValid
NSUInteger postCount = [postDict count];
NSMutableArray *buildArray = [[NSMutableArray alloc] initWithCapacity:postCount];
for (NSString *key in postDict) {
//post data is key=value&key=value&key=value...
// start with key
NSMutableString *arrayLine = [NSMutableString stringWithString:key];
[arrayLine appendString:#"="];
// analyze and then append value
id postValue = [postDict objectForKey:key];
if ([postValue isKindOfClass:[NSNumber class]]) {
NSString *valueString = [NSString stringWithFormat:#"%#",postValue];
[arrayLine appendString:valueString];
}
else if ([postValue isKindOfClass:[NSString class]]) {
NSString *urlEncodedString = [self urlEncodeValue:postValue];
[arrayLine appendString:urlEncodedString];
}
else {
NSLog(#"postKey: %#, postValue class:%#", key, [postValue class]);
NSError *jsonError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postValue
options:0
error:&jsonError];
if (jsonError != nil) {
NSLog(#"JSON serialization failed: %# - %#", [jsonError localizedDescription], [jsonError userInfo]);
NSLog(#"value: %#", postValue);
}
else {
// need to urlencode
NSString *stringifyJSON = [NSString stringWithUTF8String:[jsonData bytes]];
NSString *urlJSONstring = [self urlEncodeValue:stringifyJSON];
[arrayLine appendString:urlJSONstring];
}
}
[buildArray addObject:arrayLine];
}
NSString *postString = [buildArray componentsJoinedByString:#"&"];
NSData *postData = [postString dataUsingEncoding:NSUTF8StringEncoding];
//testing
NSLog(#"Post Dict: %#", postDict);
NSLog(#"Post Array: %#", buildArray);
NSLog(#"Post String: %#", postString);
NSLog(#"Post Data: %#", [NSString stringWithUTF8String:[postData bytes]]);
return postData;
}
My //testing log results:
Post Dict: {
authenticationString = b3210c0bc6d2c47f4c2f7eeea12e063d;
dataMode = updateSingle;
dateCreated = "374300293.81108";
dateModified = "374609294.313093";
dateSynced = "374610683.588062";
entityName = CommodityTypes;
myName = 21;
sortKey = 21;
username = iPhoneAdamek;
usernameString = iPhoneAdamek;
uuidKey = "53403EAE-DD4F-4226-A979-316EF7F43991";
}
Post Dict looks good. Just what I wanted.
2012-11-14 13:31:23.640 FoodyU[11393:907] Post Array: (
"myName=21",
"dataMode=updateSingle",
"dateSynced=374610683.588062",
"uuidKey=53403EAE-DD4F-4226-A979-316EF7F43991",
"sortKey=21",
"dateModified=374609294.313093",
"entityName=CommodityTypes",
"dateCreated=374300293.81108",
"authenticationString=b3210c0bc6d2c47f4c2f7eeea12e063d",
"usernameString=iPhoneAdamek",
"username=iPhoneAdamek"
)
Post Array looks good. Strings are all set to be concatenated for a HTTP POST string.
2012-11-14 13:31:23.641 FoodyU[11393:907] Post String: myName=21&dataMode=updateSingle&dateSynced=374610683.588062&uuidKey=53403EAE-DD4F-4226-A979-316EF7F43991&sortKey=21&dateModified=374609294.313093&entityName=CommodityTypes&dateCreated=374300293.81108&authenticationString=b3210c0bc6d2c47f4c2f7eeea12e063d&usernameString=iPhoneAdamek&username=iPhoneAdamek
Post String looks good. I'm ready to convert it to data to use in [NSMutableURLRequest setHTTPBody:postData].
2012-11-14 13:31:23.643 FoodyU[11393:907] Post Data: myName=21&dataMode=updateSingle&dateSynced=374610683.588062&uuidKey=53403EAE-DD4F-4226-A979-316EF7F43991&sortKey=21&dateModified=374609294.313093&entityName=CommodityTypes&dateCreated=374300293.81108&authenticationString=b3210c0bc6d2c47f4c2f7eeea12e063d&usernameString=iPhoneAdamek&username=iPhoneAdamekoneAdamek;
usernameString = iPhoneAdamek;
uuidKey = "53403EAE-DD4F-4226-A
WTF??? How did &username=iPhoneAdamek become &username=iPhoneAdamekoneAdamek;
usernameString = iPhoneAdamek;
uuidKey = "53403EAE-DD4F-4226-A?
I'm fairly new to Cocoa. Is there something wrong with:
NSData *postData = [postString dataUsingEncoding:NSUTF8StringEncoding];
or
NSLog(#"Post Data: %#", [NSString stringWithUTF8String:[postData bytes]]);
You shouldn't be using NSLog of NSData as,
NSLog(#"Post Data: %#", [NSString stringWithUTF8String:[postData bytes]]);
Instead use it as,
NSLog(#"Post Data: %#", [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding]);
[NSString stringWithUTF8String:[postData bytes]] always returns unexpected results.
As per documentation for bytes,
bytes: Returns a pointer to the receiver’s contents.
And as per Apple documentation for stringWithUTF8String,
stringWithUTF8String:
Returns a string created by copying the data from a given C array of UTF8-encoded bytes.
Parameters: bytes - A NULL-terminated C array of bytes in UTF8 encoding.
So when you are using [postData bytes], it is not NULL-terminated and hence when you are using with stringWithUTF8String returns the data written in memory till it encounters a NULL-termination.

How to load multiple languages to IVONA SDK - text to speech

I want to load multiple languages to use IVONA SDK with SSML for iPhone.
There is no documentation for use in Xcode/objective-C, only the SDK itself is given and several C/java examples.
How can you load multiple languages for text to speach with IVONA SDK for iOS?
EDIT 1: see my code below
load the voices at first:
- (NSInteger) loadVoice: (NSString*) vox {
if(voice != nil) {
XLog(#"(voice != nil)");
[voice unload];
voice = nil;
}
NSString *pathIvona = [[NSString alloc] initWithFormat:#"%#", vox];
self.paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [self.paths objectAtIndex:0];
self.path = [self.documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#", pathIvona]];
voice = [[IvonaVoice alloc] init:instance withLibrary:self.path withVox:self.path];
[pathIvona release];
if (voice == nil) {
XLog(#"Cannot load voice");
[self setTtsError: #"Cannot load voice"];
return 0;
}
[voice setParam:#"vol" withInteger: 99];
return 1;
}
trying to load multiple languages to one streamer with (the streamer is still nil, it doesnt change):
NSArray *allVoices = [self getAvaliableVoxes];
/**
* Here the streamer is still nil,
* i cant find the mistake here.
*
*/
IvonaStreamer *streamer = [[IvonaStreamer alloc] initWithVoices:allVoices
withText:[NSString stringWithContentsOfFile:self.path
encoding:NSUTF8StringEncoding error:&error] atSpeed:[NSNumber numberWithFloat:-1]];
Method getAvailableVoices:
- (NSArray*)getAvaliableVoxes {
XLog(#"-----------------------------------entered");
self.paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [self.paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList = [manager contentsOfDirectoryAtPath:[self.paths objectAtIndex:0] error:nil];
for (NSString *s in fileList){
//XLog(#"s: %#", s);
}
NSMutableArray *pathsIvona = [[NSMutableArray alloc] init];
NSEnumerator *e = [fileList objectEnumerator];
NSString *vox;
while (vox = [e nextObject]) {
if([[vox lastPathComponent] hasPrefix:#"vox_"]) {
XLog(#"vox: %#", vox);
[pathsIvona addObject: [vox lastPathComponent]];
XLog(#"pathsIvona: %#", pathsIvona);
}
}
XLog(#"pathsIvona: %#", pathsIvona);
return [pathsIvona autorelease];
}
How can you load multiple languages in one streamer on iOS with IVONA SDK?
perhaps the objects added to the array allVoices do not conform to the expected array of initWithVoices: ...