I can't seem to find the solution to this, there are hundreds of answers but none that I can find related to this simple problem. Whatever I do to try to put the dictionary into a string, fails? Original Text:
let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers)
let jsonString = (jsonResult as AnyObject).components(separatedBy: "")
let jsonDict = jsonString as! [String: AnyObject]
//let jsonDict = jsonString as! [String: AnyObject]
//let jsonDict = jsonString as! Dictionary<String,String>
//Cast from '[String]' to unrelated type 'Dictionary<String, String>' always fails
The full code, now sort of working after @Vadian's fix.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
searchForMovie(title: "pulp_fiction")
}
func searchForMovie(title: String){
//http://www.omdbapi.com/?t=pulp+fiction
if let movie = title.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed){
let url = URL(string: "https://www.omdbapi.com/?t=\(movie)&i=xxxxxxxx&apikey=xxxxxxxx")
// this url contains the omnbapi keys which are free/
let session = URLSession.shared
let task = session.dataTask(with: url!, completionHandler: { (data, response, error) in
if error != nil {
print(error!)
} else {
if data != nil {
do {
let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? String {
let jsonArray = jsonResult.components(separatedBy: "")
print(jsonArray)
} else {
print("This JSON is (most likely) not a string")
}
let jsonDict = jsonResult as! [String: Any]
DispatchQueue.main.async {
print(jsonDict)
}
} catch {
}
}
}
})
task.resume()
}
}
}
The Result of this is:
This JSON is (most likely) not a string
["Poster": https://m.media-
amazon.com/images/M/MV5BNGNhMDIzZTUtNTBlZi00MTRlLWFjM2ItYzViMjE3YzI5MjljXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_SX300.jpg, "BoxOffice": N/A, "Language": English, Spanish, French, "Year": 1994, "Metascore": 94, "Director": Quentin Tarantino, "Rated": R, "Runtime": 154 min, "Genre": Crime, Drama, "imdbVotes": 1,548,861, "Ratings": <__NSArrayI 0x604000256a10>(
{
Source = "Internet Movie Database";
Value = "8.9/10";
},
{
Source = "Rotten Tomatoes";
Value = "94%";
},
{
Source = Metacritic;
Value = "94/100";
}
)
, "Released": 14 Oct 1994, "imdbRating": 8.9, "Awards": Won 1 Oscar. Another 62 wins & 69 nominations., "Actors": Tim Roth, Amanda Plummer, Laura Lovelace, John Travolta, "Response": True, "Country": USA, "Plot": The lives of two mob hitmen, a boxer, a gangster's wife, and a pair of diner bandits intertwine in four tales of violence and redemption., "DVD": 19 May 1998, "Title": Pulp Fiction, "Writer": Quentin Tarantino (stories), Roger Avary (stories), Quentin Tarantino, "Production": Miramax Films, "imdbID": tt0110912, "Website": N/A, "Type": movie]
First of all never use AnyObject
for JSON values in Swift 3+. They are all Any
.
The error occurs because the result of components(separatedBy
is an array ([String]
), but you cast it to a dictionary ([String:Any(Object)]
). Don't cast at all, the compiler knows the type.
And don't use .mutableContainers
in Swift, never. This option is pointless.
components(separatedBy
makes only sense if the JSON is a string. If so you have to pass the option .allowFragments
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? String {
let jsonArray = jsonResult.components(separatedBy: "")
print(jsonArray)
} else {
print("This JSON is (most likely) not a string")
}
Edit:
According to your added result the received object is apparently an dictionary, so as? String
as well as components(separatedBy:
and .allowFragments
is wrong. Try this
if let jsonDictionary = try JSONSerialization.jsonObject(with: data!) as? [String:Any] {
for (key, value) in jsonDictionary {
print(key, value)
}
} else {
print("This JSON is not a dictionary")
}