Reputation: 6384
I'm converting from Obj-c to Swift and at times it can be quite frustrating as simple task I can do in Obj-C in minutes eat up hours. I know it's part of the process of learning but grrrr all the same.
I built a test app to query iTunes with a song name and return all the results. But for the life of me I can't seem to parse the return to the individual dictionary level.
I can use this code to mine down to the level where I think I have an array of dictionaries:
if let dictData = dictJSON["Data"] as? [String:Any], let arrResults = dictData["results"] as? Array<Any> {
I can then iterate through that array like so:
for i in 1...arrResults.count {
or
for dictThisSong in arrResults {
in either case I get results like so:
{
artistId = 158038;
artistName = "Fleetwood Mac";
artistViewUrl = "https://itunes.apple.com/us/artist/fleetwood-mac/id158038?uo=4";
artworkUrl100 = "http://is2.mzstatic.com/image/thumb/Music/v4/8e/75/28/8e752885-66d0-737c-11ef-4c706672997e/source/100x100bb.jpg";
artworkUrl30 = "http://is2.mzstatic.com/image/thumb/Music/v4/8e/75/28/8e752885-66d0-737c-11ef-4c706672997e/source/30x30bb.jpg";
artworkUrl60 = "http://is2.mzstatic.com/image/thumb/Music/v4/8e/75/28/8e752885-66d0-737c-11ef-4c706672997e/source/60x60bb.jpg";
collectionCensoredName = Rumours;
collectionExplicitness = notExplicit;
collectionId = 594061854;
collectionName = Rumours;
collectionPrice = "10.99";
collectionViewUrl = "https://itunes.apple.com/us/album/the-chain/id594061854?i=594061861&uo=4";
country = USA;
currency = USD;
discCount = 1;
discNumber = 1;
isStreamable = 0;
kind = song;
previewUrl = "https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/Music/v4/04/1d/85/041d85eb-f1fe-2d47-1ec7-2540582cece7/mzaf_3322367551095292692.plus.aac.p.m4a?accessKey=1516884136_9174591730773045036_io%2Bc9w6hmWHjPZOpZEgG1nZm9Hm%2FInFnTM%2FT3k8%2BoQZZW2ymomMWeZ8jGkN4TfX85U5U4WRYpxPN8e2svlMmBLE8boGG4aya9izAo%2FIvIMOZ4qt6XPuQQc5JstA%2FmihUGdKsa1Nbov9joyxnTnm7UlpKY2ZsqomfNv4SsJGfDG3cCgxtBoAOKR7Pj42lDYQN1jnRVqusi4Cpf9fHOXb5uA%3D%3D";
primaryGenreName = Rock;
releaseDate = "1977-02-04T08:00:00Z";
trackCensoredName = "The Chain";
trackCount = 11;
trackExplicitness = notExplicit;
trackId = 594061861;
trackName = "The Chain";
trackNumber = 7;
trackPrice = "1.29";
trackTimeMillis = 270213;
trackViewUrl = "https://itunes.apple.com/us/album/the-chain/id594061854?i=594061861&uo=4";
wrapperType = track;
}
If I do a type of check, I get NSDictionary:
print(type(of: dictThisSong))
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI...
But if I try to print dictThisSong["artistName"] I get a Type "Any" has no subscript members error.
So, then I thought maybe I have to cast to NSDictionary, but that throws an error:
Cannot convert value of type Array to NSDictionary, same if I try to cast to Dictionary
So it seems to me the error message is saying I am trying to cast an Array to a Dictionary but the type of print out says I am already working with a Dictionary. Any help would be appreciated.
Full code:
func parseJSONResults(dictJSON:Dictionary<String, Any>) {
if let dictData = dictJSON["Data"] as? [String:Any], let arrResults = dictData["results"] as? Array<Any> {
for dictThisSong in arrResults {
print(dictThisSong)
}
} else {
print(dictJSON)
}
}
Upvotes: 0
Views: 47
Reputation: 285079
You are fighting the strong type system. Help the compiler than the compiler will help you.
[Any]
is an array of I-have-no-idea-what-it-is but you do know that's an array of dictionaries, so cast it to [[String:Any]]
if let dictData = dictJSON["Data"] as? [String:Any],
let arrResults = dictData["results"] as? [[String:Any]] { ...
Upvotes: 1