How best to traverse API information with iOS - objective-c

Is there any easier way of traversing array/dictionaries without creating a lot of separate NSArrays/NSDictionaries? I know you can traverse nested dictionaries with dot notation and value at keypath, but what about when arrays are involved?
For example:
At the moment if I want to get at the object at feed.entry.link[4].href in the API result below, I have to define an array at keypath "feed.entry", then assign its first entry as a dictionary, then define an array at keypath "link" and access its fourth entry as a dictionary, and then access its value at "href".
Is this normal?
received {
encoding = "UTF-8";
feed = {
entry = (
{
author = (
{
name = {
"$t" = swdestiny;
};
uri = {
"$t" = "https://gdata.youtube.com/feeds/api/users/swdestiny";
};
}
);
category = (
{
scheme = "http://schemas.google.com/g/2005#kind";
term = "http://gdata.youtube.com/schemas/2007#video";
},
{
label = Entertainment;
scheme = "http://gdata.youtube.com/schemas/2007/categories.cat";
term = Entertainment;
},
{
scheme = "http://gdata.youtube.com/schemas/2007/keywords.cat";
term = Star;
},
{
scheme = "http://gdata.youtube.com/schemas/2007/keywords.cat";
term = Wars;
},
{
scheme = "http://gdata.youtube.com/schemas/2007/keywords.cat";
term = Episode;
},
{
scheme = "http://gdata.youtube.com/schemas/2007/keywords.cat";
term = 3;
},
{
scheme = "http://gdata.youtube.com/schemas/2007/keywords.cat";
term = Revenge;
},
{
scheme = "http://gdata.youtube.com/schemas/2007/keywords.cat";
term = of;
},
{
scheme = "http://gdata.youtube.com/schemas/2007/keywords.cat";
term = the;
},
{
scheme = "http://gdata.youtube.com/schemas/2007/keywords.cat";
term = Sith;
}
);
content = {
"$t" = "sw-destiny.net Trailer for Revenge of the Sith";
type = text;
};
"gd$comments" = {
"gd$feedLink" = {
countHint = 1567;
href = "https://gdata.youtube.com/feeds/api/videos/9kdEsZH5ohc/comments";
rel = "http://gdata.youtube.com/schemas/2007#comments";
};
};
"gd$rating" = {
average = "4.7729683";
max = 5;
min = 1;
numRaters = 1132;
rel = "http://schemas.google.com/g/2005#overall";
};
id = {
"$t" = "http://gdata.youtube.com/feeds/api/videos/9kdEsZH5ohc";
};
link = (
{
href = "https://www.youtube.com/watch?v=9kdEsZH5ohc&feature=youtube_gdata";
rel = alternate;
type = "text/html";
},
{
href = "https://gdata.youtube.com/feeds/api/videos/9kdEsZH5ohc/responses";
rel = "http://gdata.youtube.com/schemas/2007#video.responses";
type = "application/atom+xml";
},
{
href = "https://gdata.youtube.com/feeds/api/videos/9kdEsZH5ohc/related";
rel = "http://gdata.youtube.com/schemas/2007#video.related";
type = "application/atom+xml";
},
{
href = "https://m.youtube.com/details?v=9kdEsZH5ohc";
rel = "http://gdata.youtube.com/schemas/2007#mobile";
type = "text/html";
},
{
href = "https://gdata.youtube.com/feeds/api/videos/9kdEsZH5ohc";
rel = self;
type = "application/atom+xml";
}
);
"media$group" = {
"media$category" = (
{
"$t" = Entertainment;
label = Entertainment;
scheme = "http://gdata.youtube.com/schemas/2007/categories.cat";
}
);
"media$content" = (
{
duration = 151;
expression = full;
isDefault = true;
medium = video;
type = "application/x-shockwave-flash";
url = "https://www.youtube.com/v/9kdEsZH5ohc?version=3&f=videos&app=youtube_gdata";
"yt$format" = 5;
},
{
duration = 151;
expression = full;
medium = video;
type = "video/3gpp";
url = "rtsp://v2.cache4.c.youtube.com/CiILENy73wIaGQkXovmRsURH9hMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp";
"yt$format" = 1;
},
{
duration = 151;
expression = full;
medium = video;
type = "video/3gpp";
url = "rtsp://v2.cache5.c.youtube.com/CiILENy73wIaGQkXovmRsURH9hMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp";
"yt$format" = 6;
}
);
"media$description" = {
"$t" = "sw-destiny.net Trailer for Revenge of the Sith";
type = plain;
};
"media$keywords" = {
"$t" = "Star, Wars, Episode, 3, Revenge, of, the, Sith";
};
"media$player" = (
{
url = "https://www.youtube.com/watch?v=9kdEsZH5ohc&feature=youtube_gdata_player";
}
);
"media$thumbnail" = (
{
height = 360;
time = "00:01:15.500";
url = "http://i.ytimg.com/vi/9kdEsZH5ohc/0.jpg";
width = 480;
},
{
height = 90;
time = "00:00:37.750";
url = "http://i.ytimg.com/vi/9kdEsZH5ohc/1.jpg";
width = 120;
},
{
height = 90;
time = "00:01:15.500";
url = "http://i.ytimg.com/vi/9kdEsZH5ohc/2.jpg";
width = 120;
},
{
height = 90;
time = "00:01:53.250";
url = "http://i.ytimg.com/vi/9kdEsZH5ohc/3.jpg";
width = 120;
}
);
"media$title" = {
"$t" = "Star Wars Episode 3 Revenge of the Sith Trailer";
type = plain;
};
"yt$duration" = {
seconds = 151;
};
};
published = {
"$t" = "2007-05-23T03:31:54.000Z";
};
title = {
"$t" = "Star Wars Episode 3 Revenge of the Sith Trailer";
type = text;
};
updated = {
"$t" = "2012-02-20T17:14:37.000Z";
};
"yt$statistics" = {
favoriteCount = 763;
viewCount = 796719;
};
}
);
xmlns = "http://www.w3.org/2005/Atom";
"xmlns$gd" = "http://schemas.google.com/g/2005";
"xmlns$media" = "http://search.yahoo.com/mrss/";
"xmlns$yt" = "http://gdata.youtube.com/schemas/2007";
};
version = "1.0";
}

Related

Updating Adobe Illustrator content with script, without closing GUI

I am currently building an Adobe Illustrator Script, which starts a GUI and performs some text changes within the open Illustrator file. Unfortunately, the changes are only seen after closing the GUI. Is there some kind of way to preview the changes triggered by the GUI?
Here is what I have so far:
function startGUI() {
// DIALOG
// ======
var dialog = new Window("dialog");
dialog.text = "Dialog";
dialog.orientation = "column";
dialog.alignChildren = ["center","top"];
dialog.spacing = 10;
dialog.margins = 16;
// GRPNAME
// =======
var grpName = dialog.add("group", undefined, {name: "grpName"});
grpName.orientation = "row";
grpName.alignChildren = ["left","center"];
grpName.spacing = 10;
grpName.margins = 0;
var titleName = grpName.add("statictext", undefined, undefined, {name: "titleName"});
titleName.text = "Name";
titleName.preferredSize.width = 64;
var valName = grpName.add('edittext {properties: {name: "valName"}}');
valName.text = "Ela Ayah Kayis";
valName.preferredSize.width = 200;
// GRPFONTSIZE
// ===========
var grpFontSize = dialog.add("group", undefined, {name: "grpFontSize"});
grpFontSize.preferredSize.width = 250;
grpFontSize.orientation = "row";
grpFontSize.alignChildren = ["left","top"];
grpFontSize.spacing = 10;
grpFontSize.margins = 0;
grpFontSize.alignment = ["left","top"];
var titleFontSize = grpFontSize.add("statictext", undefined, undefined, {name: "titleFontSize"});
titleFontSize.text = "Font Size";
titleFontSize.preferredSize.width = 64;
var valFontSize = grpFontSize.add('edittext {properties: {name: "valFontSize"}}');
valFontSize.text = "15";
valFontSize.preferredSize.width = 30;
valFontSize.alignment = ["center","center"];
var titleFontSizeUnit = grpFontSize.add("statictext", undefined, undefined, {name: "titleFontSizeUnit"});
titleFontSizeUnit.text = "pt";
titleFontSizeUnit.alignment = ["left","center"];
var sliderFontSize = grpFontSize.add("slider", undefined, undefined, undefined, undefined, {name: "sliderFontSize"});
sliderFontSize.minvalue = 11;
sliderFontSize.maxvalue = 15;
sliderFontSize.value = 15;
sliderFontSize.preferredSize.width = 135;
sliderFontSize.onChanging = function(){
valFontSize.text = Math.round(sliderFontSize.value)
}
// DIALOG
// ======
var divider1 = dialog.add("panel", undefined, undefined, {name: "divider1"});
divider1.alignment = "fill";
// GROUP BUTTONS
// =============
var group1 = dialog.add("group", undefined, {name: "group1"});
group1.orientation = "row";
group1.alignChildren = ["right","center"];
group1.spacing = 10;
group1.margins = 0;
group1.alignment = ["center","top"];
var btnReplaceNames = group1.add("button", undefined, undefined, {name: "btnReplaceNames"});
btnReplaceNames.text = "Replace Names";
btnReplaceNames.justify = "left";
btnReplaceNames.alignment = ["right","bottom"];
var btnClose = group1.add("button", undefined, undefined, {name: "btnClose"});
btnClose.text = "Close";
// Event Listener for the replace button
btnReplaceNames.onClick = function() {
var inputText = valName.text;
updateNames(inputText, Math.round(sliderFontSize.value));
dialog.update();
}
// Event listener for the quit button
btnClose.onClick = function() {
dialog.close(); }
dialog.show();
}
function updateNames(chosenName, fontSize) {
var txtFrames = app.activeDocument.textFrames;
$.writeln("start");
if (txtFrames.length > 0) {
for ( i = 0; i < txtFrames.length; i++ ) {
if (txtFrames[i].name == 'Text-Name') {
txtFrames[i].textRange.characterAttributes.size = fontSize;
txtFrames[i].textRange.characterAttributes.leading = fontSize;
txtFrames[i].contents = chosenName;
// $.writeln(txtFrames[i].textRange.characters.length);
// $.writeln(txtFrames[i].textRange.lines.length);
}
}
}
$.writeln("done");
}
startGUI();
Closing the GUI and starting it automatically also didn't solve the issue.
....
updateNames(inputText, Math.round(sliderFontSize.value));
dialog.update();
app.redraw(); // < add this, and it will work.
....

how can i parse and foreach json tree on objective c

2015-10-13 16:42:55.391 JsonProject[30384:1471391]
requestReply: (
{
DNumb = 512421421;
DTempData = "";
DUUID = 12;
Id = 1;
},
{
DTempData = "";
Id = 2;
},
{
DTempData = "";
Id = 3;
},
{
DTempData = "";
Id = 4;
},
{
DTempData = "";
Id = 5;
},
{
DTempData = "";
Id = 6;
},
{
DTempData = "";
Id = 7;
},
{
DNumb = String;
DTempData = "";
DUUID = String;
Id = 8;
},
{
DNumb = 1234;
DTempData = "";
DUUID = 4567;
Id = 9;
},
{
DTempData = "";
Id = 10;
},
{
DTempData = "";
Id = 11;
},
{
DTempData = "";
Id = 12;
},
{
DNumb = Message;
DTempData = "";
DUUID = isNotReal;
Id = 13;
} )
This is json data after post method,
NSDictionary* responseA = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"requestReply: %#", responseA[#"GetVerifiedDevices"]);
how can i reach members? also check is available any number or character?
i was working on C# and i do use foreach, is there parse this data?
Thanks

Parsing callback response from Tumblr

How can I parse the tumblr response in order to retrieve items such as the photo link, title etc. According to Tumblr API, it's in JSON format but I can't seem to understand how to code it. Here a snippet of the response:
{
"blog_name" = myBlogName;
"can_reply" = 0;
caption = "<p>pending again</p>";
date = "2014-01-19 15:54:22 GMT";
followed = 0;
format = html;
highlighted = ();
id = 73836876344;
"image_permalink" = "http://bantaybayan.tumblr.com/image/73836876344";
liked = 0;
"note_count" = 0;
photos = (
{
"alt_sizes" = (
{
height = 558;
url = "http://24.media.tumblr.com/f3fc43d081e3a6366e794b4f94a82d37/tumblr_mzno6mMXgr1tnzku0o1_1280.jpg";
width = 740;
},
{
height = 377;
url = "http://31.media.tumblr.com/f3fc43d081e3a6366e794b4f94a82d37/tumblr_mzno6mMXgr1tnzku0o1_500.jpg";
width = 500;
},
{
height = 302;
url = "http://24.media.tumblr.com/f3fc43d081e3a6366e794b4f94a82d37/tumblr_mzno6mMXgr1tnzku0o1_400.jpg";
width = 400;
},
{
height = 189;
url = "http://25.media.tumblr.com/f3fc43d081e3a6366e794b4f94a82d37/tumblr_mzno6mMXgr1tnzku0o1_250.jpg";
width = 250;
},
{
height = 75;
url = "http://31.media.tumblr.com/f3fc43d081e3a6366e794b4f94a82d37/tumblr_mzno6mMXgr1tnzku0o1_100.jpg";
width = 100;
},
{
height = 75;
url = "http://31.media.tumblr.com/f3fc43d081e3a6366e794b4f94a82d37/tumblr_mzno6mMXgr1tnzku0o1_75sq.jpg";
width = 75;
}
);
caption = "";
"original_size" = {
height = 558;
url = "http://24.media.tumblr.com/f3fc43d081e3a6366e794b4f94a82d37/tumblr_mzno6mMXgr1tnzku0o1_1280.jpg";
width = 740;
};
}
);
"post_url" = "http://bantaybayan.tumblr.com/post/73836876344/pending-again";
"reblog_key" = LUOtTeAe;
"short_url" = "http://tmblr.co/Z89Zxo14n1L8u";
slug = "pending-again";
state = published;
tags = (
);
timestamp = 1390146862;
type = photo;
}
Thanks in advance
First of all, this doesn't look like JSON. Check it with a validator like JSONLint
It's easier if you use an editor for JSON data. There a lots of free online services http://jsoneditoronline.org/
For Objective-C, this SO question might help you out: Parsing JSON using Objective-C

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]

My XML response:
{
"S:Envelope" = {
"S:Body" = {
"ns2:getMatchListResponse" = {
item = (
{
answerTime = {
text = 30;
};
challengerAppealsGranted = {
text = "0 of 16";
};
challengerHandle = {
text = manish;
};
challengerMatchesPlayed = {
text = 93;
};
challengerPic = {
text = "image.png";
};
challengerScore = {
text = 0;
};
challengerlosses = {
text = 0;
};
challengerwins = {
text = 4;
};
handle1 = {
text = sahni;
};
handle1AppealsGranted = {
text = 5;
};
handle1MatchesPlayed = {
text = 84;
};
handle1Response = {
text = Pending;
};
handle1Score = {
text = 0;
};
handle1losses = {
text = 0;
};
handle1wins = {
text = 1;
};
handle2MatchesPlayed = {
text = 0;
};
handle2Score = {
text = 0;
};
handle2losses = {
text = 0;
};
handle2wins = {
text = 0;
};
handle3MatchesPlayed = {
text = 0;
};
handle3Score = {
text = 0;
};
handle3losses = {
text = 0;
};
handle3wins = {
text = 0;
};
idMatch = {
text = 750;
};
isAppeal = {
text = false;
};
isFreeForm = {
text = false;
};
isMultichoiceQuestion = {
text = false;
};
isPublic = {
text = false;
};
matchName = {
text = ewtwert;
};
matchStartThresholdTime = {
text = "4 days 7 hrs";
};
matchStatus = {
text = wait;
};
matchType = {
text = Private;
};
noOfPlayers = {
text = 2;
};
priorityInList = {
text = 0;
};
scoreToWin = {
text = 5;
};
timeDuration = {
text = "5 days";
};
turnChangesIn = {
text = 0;
};
},
{
answerTime = {
text = 30;
};
challengerAppealsGranted = {
text = "0 of 16";
};
challengerHandle = {
text = manish;
};
challengerMatchesPlayed = {
text = 93;
};
challengerPic = {
text = "image.png";
};
challengerScore = {
text = 0;
};
challengerlosses = {
text = 0;
};
challengerwins = {
text = 4;
};
handle1MatchesPlayed = {
text = 0;
};
handle1Score = {
text = 0;
};
handle1losses = {
text = 0;
};
handle1wins = {
text = 0;
};
handle2MatchesPlayed = {
text = 0;
};
handle2Score = {
text = 0;
};
handle2losses = {
text = 0;
};
handle2wins = {
text = 0;
};
handle3MatchesPlayed = {
text = 0;
};
handle3Score = {
text = 0;
};
handle3losses = {
text = 0;
};
handle3wins = {
text = 0;
};
idMatch = {
text = 749;
};
isAppeal = {
text = false;
};
isFreeForm = {
text = false;
};
isMultichoiceQuestion = {
text = false;
};
isPublic = {
text = false;
};
matchName = {
text = gfhf;
};
matchStartThresholdTime = {
text = "4 days 6 hrs";
};
matchStatus = {
text = wait;
};
matchType = {
text = Public;
};
noOfPlayers = {
text = 2;
};
priorityInList = {
text = 0;
};
scoreToWin = {
text = 5;
};
timeDuration = {
text = "5 days";
};
turnChangesIn = {
text = 0;
};
}
);
"xmlns:ns2" = "http://services.tgs.com/";
};
};
"xmlns:S" = "http://schemas.xmlsoap.org/soap/envelope/";
};
}
I need value of key "matchStartThresholdTime".
I do:
NSDictionary *dictResult = [XMLReader dictionaryForXMLString:responseString error:nil];
NSDictionary *Enveloper = [dictResult objectForKey:#"S:Envelope"];
NSDictionary *Body = [Enveloper objectForKey:#"S:Body"];
NSDictionary *profileDetails = [Body objectForKey:#"ns2:getMatchListResponse"];
NSMutableArray *items = [profileDetails objectForKey:#"item"];
// NSLog(#"items===>%#",items);
NSDictionary *temp1;
for(temp1 in items)
{
thresholdTime = [NSString stringWithFormat:#"%#",[[temp1 objectForKey:#"matchStartThresholdTime"]objectForKey:#"text"]];...thresholdTime is NSString object.......and this line causes exception
//NSLog(#"time is===>%#",[[temp1 objectForKey:#"matchStartThresholdTime"]objectForKey:#"text"]);
}
What is the problem here?
Temp1 contains an NSString Object and not the NSDictionary, that you expect.
When dealing with JSON it is wise always to (double) check if a received object is really of the type that you expect. Always use
if ([temp1 isKindOfClass:[NSDictionary class]]) ...
or so.

extracting information from NSDictionary

I have a NSDictionary response from a Flickr api request and it's description looks like this:
self.userInfo: {
"_text" = "\n\n";
person = {
"_text" = "\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n";
description = {
};
iconfarm = 0;
iconserver = 0;
id = "83943196#N02";
ispro = 0;
location = {
};
"mbox_sha1sum" = {
"_text" = 7b61c5d24f12345678be82c31234567830540;
};
mobileurl = {
"_text" = "http://m.flickr.com/photostream.gne?id=12345678";
};
nsid = "12345678#N02";
"path_alias" = "";
photos = {
"_text" = "\n\t\t\n\t\t\n\t\t\n\t\t\n\t";
count = {
"_text" = 2;
};
firstdate = {
"_text" = 12345678;
};
firstdatetaken = {
"_text" = "2012-08-01 12:46:38";
};
views = {
"_text" = 0;
};
};
photosurl = {
"_text" = "http://www.flickr.com/photos/12345678#N02/";
};
profileurl = {
"_text" = "http://www.flickr.com/people/12345678#N02/";
};
realname = {
"_text" = "Me TheUser";
};
timezone = {
label = "Pacific Time (US & Canada); Tijuana";
offset = "-08:00";
};
username = {
"_text" = metheuser;
};
};
stat = ok;
}
I'm having truoble figuring out how to extract the realname value into a NSString.
I've tried:
NSString * temp = [self.userInfo valueForKey:#"realname"];
NSLog (#"FL: nameOfSignedInUser. nameself.userInfo: %#", temp.debugDescription);
but that comes back as nil.
thank you!
NSString *name = [self.userInfo valueForKeyPath:#"person.realname._text"];
NSString *realName = [[[self.userInfo objectForKey:#"person"] objectForKey:#"realname"] objectForKey:#"_text"];