I'm trying to make requests using AlamoFire and decode them using the built-in .responseDecodable
handler. The API endpoint I'm hitting is https://api.linode.com/v4/regions
.
Request.swift
:
import Foundation
import Alamofire
func getRegions() {
AF.request("https://api.linode.com/v4/regions")
.validate()
.responseDecodable(of: Region.self) { (response) in
guard let regions = response.value else { return }
print(regions)
debugPrint("Response: \(response)")
}
}
When I built and run the binary and call getRegions()
, I get no output in the console (debug or otherwise). When I change getRegions()
and remove .responseDecodable
, like this, I get the raw JSON in the console:
let regionRequest = AF.request("https://api.linode.com/v4/regions")
regionRequest.responseJSON { (data) in
print(data)
Here is my Region model:
Region.swift
:
import Foundation
struct Region: Decodable {
enum resolvers: String, Decodable {
case ipv4, ipv6
}
let capabilities: Array<String>
let country: String
let id: String
let resolvers: Set<resolvers>
let status: String
let page: Int
let pages: Int
let results: Int
enum CodingKeys: String, CodingKey {
case capabilities
case country
case resolvers
case status
case id
case page
case pages
case results
}
}
And here is the JSON response from the API:
data = (
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
"GPU Linodes",
Kubernetes,
"Cloud Firewall",
Vlans
);
country = in;
id = "ap-west";
resolvers = {
ipv4 = "172.105.34.5,172.105.35.5,172.105.36.5,172.105.37.5,172.105.38.5,172.105.39.5,172.105.40.5,172.105.41.5,172.105.42.5,172.105.43.5";
ipv6 = "2400:8904::f03c:91ff:fea5:659,2400:8904::f03c:91ff:fea5:9282,2400:8904::f03c:91ff:fea5:b9b3,2400:8904::f03c:91ff:fea5:925a,2400:8904::f03c:91ff:fea5:22cb,2400:8904::f03c:91ff:fea5:227a,2400:8904::f03c:91ff:fea5:924c,2400:8904::f03c:91ff:fea5:f7e2,2400:8904::f03c:91ff:fea5:2205,2400:8904::f03c:91ff:fea5:9207";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
Kubernetes,
"Cloud Firewall",
Vlans
);
country = ca;
id = "ca-central";
resolvers = {
ipv4 = "172.105.0.5,172.105.3.5,172.105.4.5,172.105.5.5,172.105.6.5,172.105.7.5,172.105.8.5,172.105.9.5,172.105.10.5,172.105.11.5";
ipv6 = "2600:3c04::f03c:91ff:fea9:f63,2600:3c04::f03c:91ff:fea9:f6d,2600:3c04::f03c:91ff:fea9:f80,2600:3c04::f03c:91ff:fea9:f0f,2600:3c04::f03c:91ff:fea9:f99,2600:3c04::f03c:91ff:fea9:fbd,2600:3c04::f03c:91ff:fea9:fdd,2600:3c04::f03c:91ff:fea9:fe2,2600:3c04::f03c:91ff:fea9:f68,2600:3c04::f03c:91ff:fea9:f4a";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
Kubernetes,
"Cloud Firewall",
Vlans
);
country = au;
id = "ap-southeast";
resolvers = {
ipv4 = "172.105.166.5,172.105.169.5,172.105.168.5,172.105.172.5,172.105.162.5,172.105.170.5,172.105.167.5,172.105.171.5,172.105.181.5,172.105.161.5";
ipv6 = "2400:8907::f03c:92ff:fe6e:ec8,2400:8907::f03c:92ff:fe6e:98e4,2400:8907::f03c:92ff:fe6e:1c58,2400:8907::f03c:92ff:fe6e:c299,2400:8907::f03c:92ff:fe6e:c210,2400:8907::f03c:92ff:fe6e:c219,2400:8907::f03c:92ff:fe6e:1c5c,2400:8907::f03c:92ff:fe6e:c24e,2400:8907::f03c:92ff:fe6e:e6b,2400:8907::f03c:92ff:fe6e:e3d";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
Kubernetes,
"Cloud Firewall"
);
country = us;
id = "us-central";
resolvers = {
ipv4 = "72.14.179.5,72.14.188.5,173.255.199.5,66.228.53.5,96.126.122.5,96.126.124.5,96.126.127.5,198.58.107.5,198.58.111.5,23.239.24.5";
ipv6 = "2600:3c00::2,2600:3c00::9,2600:3c00::7,2600:3c00::5,2600:3c00::3,2600:3c00::8,2600:3c00::6,2600:3c00::4,2600:3c00::c,2600:3c00::b";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
Kubernetes,
"Cloud Firewall"
);
country = us;
id = "us-west";
resolvers = {
ipv4 = "173.230.145.5,173.230.147.5,173.230.155.5,173.255.212.5,173.255.219.5,173.255.241.5,173.255.243.5,173.255.244.5,74.207.241.5,74.207.242.5";
ipv6 = "2600:3c01::2,2600:3c01::9,2600:3c01::5,2600:3c01::7,2600:3c01::3,2600:3c01::8,2600:3c01::4,2600:3c01::b,2600:3c01::c,2600:3c01::6";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Cloud Firewall",
Vlans
);
country = us;
id = "us-southeast";
resolvers = {
ipv4 = "74.207.231.5,173.230.128.5,173.230.129.5,173.230.136.5,173.230.140.5,66.228.59.5,66.228.62.5,50.116.35.5,50.116.41.5,23.239.18.5";
ipv6 = "2600:3c02::3,2600:3c02::5,2600:3c02::4,2600:3c02::6,2600:3c02::c,2600:3c02::7,2600:3c02::2,2600:3c02::9,2600:3c02::8,2600:3c02::b";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
"Object Storage",
"GPU Linodes",
Kubernetes
);
country = us;
id = "us-east";
resolvers = {
ipv4 = "66.228.42.5,96.126.106.5,50.116.53.5,50.116.58.5,50.116.61.5,50.116.62.5,66.175.211.5,97.107.133.4,207.192.69.4,207.192.69.5";
ipv6 = "2600:3c03::7,2600:3c03::4,2600:3c03::9,2600:3c03::6,2600:3c03::3,2600:3c03::c,2600:3c03::5,2600:3c03::b,2600:3c03::2,2600:3c03::8";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
Kubernetes,
"Cloud Firewall"
);
country = uk;
id = "eu-west";
resolvers = {
ipv4 = "178.79.182.5,176.58.107.5,176.58.116.5,176.58.121.5,151.236.220.5,212.71.252.5,212.71.253.5,109.74.192.20,109.74.193.20,109.74.194.20";
ipv6 = "2a01:7e00::9,2a01:7e00::3,2a01:7e00::c,2a01:7e00::5,2a01:7e00::6,2a01:7e00::8,2a01:7e00::b,2a01:7e00::4,2a01:7e00::7,2a01:7e00::2";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
"Object Storage",
"GPU Linodes",
Kubernetes
);
country = sg;
id = "ap-south";
resolvers = {
ipv4 = "139.162.11.5,139.162.13.5,139.162.14.5,139.162.15.5,139.162.16.5,139.162.21.5,139.162.27.5,103.3.60.18,103.3.60.19,103.3.60.20";
ipv6 = "2400:8901::5,2400:8901::4,2400:8901::b,2400:8901::3,2400:8901::9,2400:8901::2,2400:8901::8,2400:8901::7,2400:8901::c,2400:8901::6";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
"Object Storage",
"GPU Linodes",
Kubernetes
);
country = de;
id = "eu-central";
resolvers = {
ipv4 = "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5";
ipv6 = "2a01:7e01::5,2a01:7e01::9,2a01:7e01::7,2a01:7e01::c,2a01:7e01::2,2a01:7e01::4,2a01:7e01::3,2a01:7e01::6,2a01:7e01::b,2a01:7e01::8";
};
status = ok;
},
{
capabilities = (
Linodes,
NodeBalancers,
"Block Storage",
Kubernetes
);
country = jp;
id = "ap-northeast";
resolvers = {
ipv4 = "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5";
ipv6 = "2400:8902::3,2400:8902::6,2400:8902::c,2400:8902::4,2400:8902::2,2400:8902::8,2400:8902::7,2400:8902::5,2400:8902::b,2400:8902::9";
};
status = ok;
}
);
page = 1;
pages = 1;
results = 11;
})
What am I doing wrong here? I suspect it's something with the Region struct but I haven't been able to figure it out. Any help would be appreciated, thanks!
Update:
I simplified my Region model a bit and also added optionals:
struct Data: Codable {
let data: [Region]
let page, pages, results: Int
}
struct Region: Codable {
let capabilities: [String]?
let country, id: String?
let status: String?
let resolvers: Resolvers?
enum CodingKeys: String, CodingKey {
case country
case id
case status
case capabilities
case resolvers
}
}
struct Resolvers: Codable {
let ipv4, ipv6: String
}
I'm now getting a successful response using AlamoFire (though the everything is nil
– progress though!):
success(.Region(capabilities: nil, country: nil, id: nil, status: nil, resolvers: nil))
Thanks to everyone who commented! I was able to sort this out by adding a missing coding key. I created Regions.swift
, which looks like this:
import Foundation
struct Regions: Decodable {
let all: [Region]
enum CodingKeys: String, CodingKey {
case all = "data"
}
}
The API response is encapsulated in data
. Once I added this coding key, I was able to get the decoded response I was looking for:
AF.request("https://api.linode.com/v4/regions")
.validate()
.responseDecodable(of: Regions.self) {(response) in
guard let regions = response.value else {return}
print(regions.all[0].self)
}
Response:
Region(capabilities: ["Linodes", "NodeBalancers", "Block Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans"], country: "in", id: "ap-west", status: "ok", resolvers: QuickCloud.Resolvers(ipv4: "172.105.34.5,172.105.35.5,172.105.36.5,172.105.37.5,172.105.38.5,172.105.39.5,172.105.40.5,172.105.41.5,172.105.42.5,172.105.43.5", ipv6: "2400:8904::f03c:91ff:fea5:659,2400:8904::f03c:91ff:fea5:9282,2400:8904::f03c:91ff:fea5:b9b3,2400:8904::f03c:91ff:fea5:925a,2400:8904::f03c:91ff:fea5:22cb,2400:8904::f03c:91ff:fea5:227a,2400:8904::f03c:91ff:fea5:924c,2400:8904::f03c:91ff:fea5:f7e2,2400:8904::f03c:91ff:fea5:2205,2400:8904::f03c:91ff:fea5:9207"))