I have a problem with Xcode and SwiftUI.
I need to put a [String:Any]
on a label but it says I need [String:String]
to do it. I don't know how to convert [String:Any]
to [String:String]
.
import UIKit
class ViewController: UIViewController {
let apiService = WeatherAPIService()
@IBOutlet weak var label: UILabel!
@IBAction func button(_ sender: Any) {
let url = URL(string: "https://api.kanye.rest/")
apiService.executeWebRequest(urlToExecute: url!) { (responseDict, error) in
print(responseDict ?? "")
var quote = responseDict
}
func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
}
func executeWebRequest(urlToExecute : URL, completionHandler : @escaping ([String:Any]?, Error?)->Void) {
let sharedSession = URLSession.shared
let webRequest = URLRequest(url: urlToExecute)
let dataTask = sharedSession.dataTask(with: webRequest) { (webData, urlResponse, apiError) in
guard let unwrappedData = webData else {
completionHandler(nil, apiError)
return
}
do{
let jsonResponse = try JSONSerialization.jsonObject(with: unwrappedData, options: .mutableContainers) as? [String:Any]
completionHandler(jsonResponse, nil)
} catch {
print(error.localizedDescription)
completionHandler(nil, error)
}
}
dataTask.resume()
}
}
CodePudding user response:
You can cast from [String: Any] to [String: String] like this:
func myFunc(_ dict: [String: Any]) -> [String: String] {
var newDict: [String: String] = [:]
for key in dict.keys {
if let value = dict[key] as? String {
newDict[key] = value
}
}
return newDict
}
Usage:
let dict: [String: Any] = ["1": 4,
"2": "a",
"3": 3.4,
"4": "b"]
let newDict = myFunc(dict)
print(">>>> \(newDict)")
output:
>>>> ["4": "b", "2": "a"]
CodePudding user response:
A dictionary of type [String: Any]
can contain key/value pairs of type [String: String]
as well as pairs where. the value can be any type.
You could use compactMap()
to convert the subset of key/value pairs in your dictionary that are of type [String: String]
to a dictionary of type [String: String]
with code like this:
let aDict: [String: Any] = ["key1": 1, "key2": "two", "key3": 3.1415, "key4": "four", "key5": "five"]
let dictWithStrings = aDict.compactMap { (item) -> [String: String]? in
guard let stringValue = item.value as? String else { return nil }
return [item.key: stringValue]
}
Alternately, you could map every entry in your dictionary to [String:String]
using String(describing:)
:
let dictWithStrings = aDict.map { (item) -> [String: String] in
return [item.key: String(describing: item.value)]
}