I am parsing twiter search api json data with NSJSONSerialization.Requirement is to search tweets by hashtag.In Twitter api console tool I am correctly getting data about 15 tweets.
written code is
if let results: NSDictionary = NSJSONSerialization .JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments , error: errorPointer) as? NSDictionary {
}
I am getting results value as
{
"search_metadata" = {
"completed_in" = "0.05";
count = 15;
"max_id" = 680240431771156480;
"max_id_str" = 680240431771156480;
"next_results" = "?max_id=680240407322689535&q=%23ChristmasEve&include_entities=1";
query = "%23ChristmasEve";
"refresh_url" = "?since_id=680240431771156480&q=%23ChristmasEve&include_entities=1";
"since_id" = 0;
"since_id_str" = 0;
};
statuses = (
{
contributors = "<null>";
coordinates = "<null>";
"created_at" = "Fri Dec 25 04:15:31 +0000 2015";
entities = {
hashtags = (
{
indices = (
0,
13
);
text = ChristmasEve;
},
{
which is incomplete.
I even tried using SwiftyJSon library but I am getting similar results.
Is there any way to get statuses/Tweet info value without using any external library?
Given the fact that you mentioned you are getting multiple tweets (15), the JSON data you're getting back from the API possibly is an array, not a dictionary. It's a good practice to handle both cases when you make network calls:
do {
let object = try NSJSONSerialization.JSONObjectWithData(data, options: [])
if let dictionary = object as? [NSObject: AnyObject] {
// Handle dictionary
} else if let array = object as? [[NSObject: AnyObject]] {
// Handle array
}
} catch {
}
Related
Here is my JSON response for a particular API.
Case 1
ChallengeConfiguration = {
AnswerAttemptsAllowed = 0;
ApplicantChallengeId = 872934636;
ApplicantId = 30320480;
CorrectAnswersNeeded = 0;
MultiChoiceQuestion = (
{
FullQuestionText = "From the following list, select one of your current or previous employers.";
QuestionId = 35666244;
SequenceNumber = 1;
},
{
FullQuestionText = "What color is/was your 2010 Pontiac Grand Prix?";
QuestionId = 35666246;
SequenceNumber = 2;
}
)
}
The key "MultiChoiceQuestion" returns an array with two questions. So here is my code.
let QuestionArray:NSArray = dict1.objectForKey("ChallengeConfiguration")?.objectForKey("MultiChoiceQuestion") as! NSArray
Case 2
ChallengeConfiguration =
{
AnswerAttemptsAllowed = 0;
ApplicantChallengeId = 872934636;
ApplicantId = 30320480;
CorrectAnswersNeeded = 0;
MultiChoiceQuestion = {
FullQuestionText = "From the following list, select one of your
current or previous employers.";
QuestionId = 35666244;
SequenceNumber = 1;
}
}
For Case 2 my code does not work and app crashes because it returns a dictionary for that specific Key. So how could I write a generic code that would work for all objects?
It looks like the key can contain either an array of dictionary values or a dictionary, so you just need to try casting to see which one you have.
so I would likely do it like this:
if let arr = dict1.objectForKey("ChallengeConfiguration")?.objectForKey("MultiChoiceQuestion") as? Array {
// parse multiple items as an array
} else if let arr = dict1.objectForKey("ChallengeConfiguration")?.objectForKey("MultiChoiceQuestion") as? [String:AnyObject] {
// parse single item from dictionary
}
You should never really use ! to force unwrap something unless you are completely certain that the value exists and is of the type you are expecting.
Use conditional logic here to test the response and parse it safely so that your app doesn't crash, even in failure.
I'm fetching data from a weather API. I'm not sure how to access the description?
"weather": <__NSSingleObjectArrayI 0x608000012910>(
{
description = "overcast clouds";
icon = 04n;
id = 804;
main = Clouds;
}
)
I tried:
print(weatherDict["weather"]!.description!)
It just gave me this:
(
{
description = "overcast clouds";
icon = 04n;
id = 804;
main = Clouds;
}
)
How do I properly access the description?
weather contains an array of dictionaries.
description is a key in the first item of the array.
The code unwraps weather safely and checks if the array is not empty:
if let weatherArray = weatherDict["weather"] as? [[String:Any]],
let weather = weatherArray.first {
print(weather["description"]) // the value is an optional.
}
I receive JSON objects that looks like the one below. How can I convert it into a format that is easily handled by Swift 2.1 ? I will receive several of these and have to put them into an array and sort by createdAt.
Optional({
comment = "<null>";
completedAt = "<null>";
createdAt = "2015-11-02 15:01:04 +0000";
paid = 1;
paidAt = "2015-11-02 15:01:04 +0000";
startedAt = "<null>";
state = request;
type = doctor;
user = KTsCySacEAiz3eDnf;
userdata = {
birthdate = "<null>";
gender = "<null>";
};
})
As in the title you say you expect a Dictionary, you can get one by simply serializate the json and cast it to a Dictionary.
do{
let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
}catch{
print("Something went wrong")
}
Where data is you json content as NSData. If you get a String you can easily convert it
let data = text.dataUsingEncoding(NSUTF8StringEncoding)
I'm not able to get data posted using the following code. I've tried all related posts on SO but still can't get it to work.
Added in request descriptor, have the NSDictionary for mapping the parameters, tried inverseMapping, ect.
var parms = WearRequestParms()
parms.Height = height
parms.Width = width
parms.Density = density
if let userId = AlpineMetricsHttpClient.GetUserId()
{
parms.UserId = userId
}
var objectManager : RKObjectManager?
objectManager = AlpineMetricsHttpClient.SetupClient()
// var mapping = RKObjectMapping(forClass:WearRequestParms.self)
var mapping = RKObjectMapping.requestMapping()
let requestMappingObjects = ["IsCircle","Height","Width","Density","UserId","WearModel","Platform"]
let dict : NSMutableDictionary = ["IsCircle":"IsCircle","Height":"Height","Width":"Width","Density":"Density","UserId":"UserId","WearModel":"WearModel","Platform":"Platform"]
mapping.addAttributeMappingsFromArray(requestMappingObjects)
// mapping.addAttributeMappingsFromDictionary(dict as [NSObject : AnyObject])
// var newRequestMapping = mapping.inverseMapping()
let requestDescriptor = RKRequestDescriptor(mapping: mapping, objectClass: WearRequestParms.self, rootKeyPath: "", method: RKRequestMethod.POST)
objectManager!.addRequestDescriptor(requestDescriptor)
// response
let responseMapping = RKObjectMapping(forClass:PostStatus.self)
var responseDescriptor = RKResponseDescriptor(
mapping: responseMapping
,method:RKRequestMethod.POST
,pathPattern : "/api/User/RegisterWearDevice"
,keyPath :""
,statusCodes : NSIndexSet(index:200))
objectManager!.addResponseDescriptor(responseDescriptor)
RKObjectManager.sharedManager().postObject(parms, path: "/api/User/RegisterWearDevice", parameters: nil,
success:{ operation, mappingResult in
NSLog("success")
defaults.setBool(true, forKey: "WearDimensionsSynced")
},
failure:{ operation, error in
NSLog("Error loading metric list': \(error!.localizedDescription)")
//return nil
}
);
I shouldn't have been using RKObjectManager.sharedManager().postObject
This caused the previous values to get overwritten or interfered with.
I switched
RKObjectManager.sharedManager().postObject
With
objectManager!.postObject
I have an application which retrieves a JSON file. Here you are a piece of my code:
Array definition
var photos: NSArray = []
How I populate the array:
ezJson().createRequest("http://myapiurl/load", type: "GET", params: nil, completion: {(returnedObject : AnyObject?, error : NSError?)in
if returnedObject{
self.photos = returnedObject as NSArray
self.tableView.reloadData()
}
})
println(self.photos)
{
created = {
date = "2014-06-13 18:35:46";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description1;
id = 3;
name = 539b286277617;
},
{
created = {
date = "2014-06-13 18:38:38";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description2;
id = 4;
name = 539b290ed8577;
}
println(self.photos[0])
{
created = {
date = "2014-06-13 18:35:46";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description1;
id = 3;
name = 539b286277617;
}
The problem is, I don't know how to get a particular item. I've tried:
println(self.photos[0]) // it works
println(self.photos[0]["name"] // Xcode crash "Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254"
println(self.photos[0].name) // returns nil
How can I access to the name parameter ?
It seems that you are casting a String to NSArray. This won't give you the effect that you want.
First of all, if you want to acces your elements by name, you want an NSDictionary.
Then it propably still won't work, as there is no implicit conversion between the types so you will have to either parse it yourself or use some JSON library.
Last : your JSON is incorrect.