I cant able to convert result into IeroLocationSave object. This below cod e says -- cannot convert value of any to IeroLocationSave type in coercion
var model = IeroLocationSave!.self
libName.fetchDataUsingPost(forURL: url, parameters: parameters, headerFiled: [:], completionHandler: {(result: Any?)-> Void in
let json = result
print("json value",json!)
model = result! as IeroLocationSave
print("actualResponse",result as? [String: AnyObject])
// guard let json = result as? [String: AnyObject] else{∫
// }
}, failureHandler: {(result: Error?)-> Void in
print("error", result ?? "nil")})
Related
I can't find a clue to add a new value to an Encodable object and then return the result as Encodable object again, as follows:
func add(pageNumber: Int, toParams params: Encodable? = nil) -> Encodable {
var parameters: [String: Any] = [:]
if let params = params {
let jsonEncoder = JSONEncoder()
if let jsonData = try? jsonEncoder.encode(params),
let jsonObject = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
parameters = jsonObject
}
}
parameters["page"] = pageNumber
return parameters
}
I need the input params to be Encodable (as in the code snippet above) and not [String:Any] as it may hold objects of different types, one of them and not limited to, is a [String:Any] dictionary.
And in case there're no input params to the function, it should return an Encodable [String: Any] dictionary that holds pageNumber.
I'm working on a pet project where I am serializing JSON using the JSONSerialization class and jsonObject(with:options:). The object is unusable until cast into a Dictionary [String: Any] or an Array [Any]. This is where the inconsistency occurs. The following is a method from one of my classes. The input is tested and valid.
private static func parse(data: Data) -> [JSONDictionary]? {
do {
let options = JSONSerialization.ReadingOptions() // rawValue = UInt 0
let otherOptions: JSONSerialization.ReadingOptions = [] // rawValue = UInt 0
let jsonAny = try JSONSerialization.jsonObject(with: data, options: otherOptions)
if let array = jsonAny as? [String: Any] {
print(array)
}
} catch {
return nil
}
return nil
}
Both of the ReadingOption objects are valid and produce valid output that can be properly cast, and print(array) is called.
However, when I use the following, invalid output is returned and can not be cast properly. Note options in the jsonObject call has an equivalent value to otherOptions in the above example.
private static func parse(data: Data) -> [JSONDictionary]? {
do {
let jsonAny = try JSONSerialization.jsonObject(with: data, options: [])
if let array = jsonAny as? [String: Any] {
print(array) // never called
}
} catch {
return nil
}
return nil
}
I thought because they have equivalent values that I could use them in place of each other. But that is not the case. Is this a bug, or am I using this incorrectly?
Edit: here is the dataset being used https://www.govtrack.us/api/v2/role?current=true&role_type=senator
The reading options are irrelevant. In Swift ReadingOptions are only useful if the expected result is not array or dictionary.
If the expected type is array or dictionary omit the options parameter.
The inconsistency is that your return type is an array ([JSONDictionary]) but the actual type is a dictionary.
private static func parse(data: Data) -> JSONDictionary? {
do {
let jsonAny = try JSONSerialization.jsonObject(with: data)
if let jsonDictionary = jsonAny as? JSONDictionary {
return jsonDictionary
}
} catch {
print(error)
return nil
}
return nil
}
It's recommended to hand over an error of a throwing method
enum SerializationError : Error {
case typeMismatch
}
private static func parse(data: Data) throws -> JSONDictionary {
let jsonAny = try JSONSerialization.jsonObject(with: data)
guard let jsonDictionary = jsonAny as? JSONDictionary else { throw SerializationError.typeMismatch }
return jsonDictionary
}
Can anyone tell me how to fix this? Im just trying to receive signals from thing speak.
`self.title = "Home"
print("Requesting data...")
Alamofire.request( "https://api.thingspeak.com/channels/290427/feeds.json", parameters: ["results": "1", "location": "false"]) // Gets the latest info from ThingSpeak
.responseJSON { response in
print("Data downloaded: \(response.result)")
if let json = response.result.value as! [String:Any] {
print(json) //see full data
if let feeds = json["feeds"] as? [String: Any] {
for feed in feeds {
print(feed["field2"])
if let temperatureStr = feed["field2"] as? String, let dateStr = feed["created_at"] as? String {
if let temperature = Double(temperatureStr){
self.label.text = "Temperature: \(temperature)°F" //Displays last updated data entry
}
The error is in the line
if let json = response.result.value as! [String:Any] {
Error message says "Initializer for conditional binding must have Optional type, not '[String : Any]'
If you wanna use conditional binding, the right side of the expression should be optional.
Change this:
if let json = response.result.value as! [String:Any]
To this:
if let json = response.result.value as? [String:Any]
That message mean that you need to have optional type so just change
if let json = response.result.value as! [String:Any] {
to
if let json = response.result.value as? [String:Any] {
i tried to get The (Name) value to a label
i used resultLabel.text = !(jsonResult["name"]) but it returns an error
Cannot subscript a value of type 'AnyObject' with an index of type 'String'
See my JSON
and does anybody know's how to get the data..
My code ....
if let url = URL(string: "http://www.omdbapi.com/?t=The+Raid&y=&plot=short&r=json") {
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in // URLSession.shared().dataTask(with: url) { (data, response, error) is now URLSession.shared.dataTask(with: url) { (data, response, error)
if error != nil {
print(error)
} else {
if let urlContent = data {
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject // Added "as anyObject" to fix syntax error in Xcode 8 Beta 6
print(jsonResult)
print(jsonResult["Title"])
resultLabel.text = (jsonResult["name"])
if let description = ((jsonResult["weather"] as? NSArray)?[0] as? NSDictionary)?["description"] as? String {
DispatchQueue.main.sync(execute: {
self.resultLabel.text = description
})
}
} catch {
print("JSON Processing Failed")
}
}
}
}
task.resume()
} else {
resultLabel.text = "Couldn't find weather for that city - please try another."
}
}
Casting the result of JSON deserialization to AnyObject is the worst you can do.
First of all the unspecified JSON type is Any and since the type is supposed to be a dictionary, cast it to [String:Any].
Further in Swift 3 the compiler must know all types which are subscripted
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: []) as! [String:Any]
let name = jsonResult["name"] as? String
print(name ?? "n/a")
if let weather = jsonResult["weather"] as? [[String:Any]], !weather.isEmpty {
if let description = weather[0]["description"] as? String {
DispatchQueue.main.async { // not sync !!
self.resultLabel.text = description
}
}
...
PS: As always, mutableContainers is meaningless in Swift and meaningless anyway if the values are only read.
I parse JSON with this :
let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers)
and get the following nested dictionary as a result
{ response = { GeoObjectCollection = { featureMember =
(
{ GeoObject = { Point = { pos = "40.275713 59.943413"; }; }; },
{ GeoObject = { Point = { pos = "40.273162 59.944292"; }; }; }
);
};
};
}
I'm trying to get the values of coordinates out of this dictionary and save them into new latutudeString and longitudeString variables
Until Xcode 8 GM it worked for me with this code:
if let jsonCoordinatesString: String = dictionary["response"]!!["GeoObjectCollection"]!!["featureMember"]!![0]["GeoObject"]!!["Point"]!!["pos"]!! as? String {
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
But since I've installed Xcode 8 GM i receive an error:
Type Any has no Subscript members
How to fix it it Swift 3 with Xcode 8 ? I've read that I can cast it but don't know exactly how to make it work with my nested dictionary in swift 3 with the latest Xcode. I've read can't resolve "Ambiguous use of subscript" but it really did not helped me in my case.
Your JSON data has this type in Swift:
[String: [String: [String: [[String: [String: [String: String]]]]]]]
I would avoid using such a too deeply nested type, but you can write something like this, if you dare use it:
enum MyError: Error {
case invalidStructure
}
do {
guard let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as? [String: [String: [String: [[String: [String: [String: String]]]]]]] else {
throw MyError.invalidStructure
}
if let jsonCoordinatesString: String = dictionary["response"]?["GeoObjectCollection"]?["featureMember"]?[0]["GeoObject"]?["Point"]?["pos"] {
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
} catch let error {
print(error)
}
But you may be hiding some irrelevant members of the JSON data, which might break this as? conversion.
So, you can go step by step, in some cases "need to" in Swift 3, like this:
do {
guard let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as? [String: AnyObject] else {
throw MyError.invalidStructure
}
if
let response = dictionary["response"] as? [String: AnyObject],
let geoObjectCollection = response["GeoObjectCollection"] as? [String: AnyObject],
let featureMember = geoObjectCollection["featureMember"] as? [[String: AnyObject]],
!featureMember.isEmpty,
let geoObject = featureMember[0]["GeoObject"] as? [String: AnyObject],
let point = geoObject["Point"] as? [String: AnyObject],
let jsonCoordinatesString = point["pos"] as? String
{
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
} catch let error {
print(error)
}
(lets are mandatory for each Optional-bindings in Swift 3. And you can change all AnyObjects to Anys, if you prefer.)
The problem is that you have not specify the type of dictionary object, you need to explicitly specify the type of dictionary object as Dictionary like this way.
let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as! [String: Any]
if let response = dictionary["response"] as? [String: Any],
let geoObjectCollection = response["GeoObjectCollection"] as? [String: Any],
let featureMember = geoObjectCollection["featureMember"] as? [[String: Any]] {
if let geoObject = featureMember[0]["GeoObject"] as? [String: Any],
let point = geoObject["Point"] as? [String: String] {
let latLongArray = point["pos"].components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
}