Parsing JSON data is one of the most fundamental skills to learn as an iOS Developer. Most apps make a network request to get data from a remote server, and once that request is executed, you’ll need to convert that data into a Swift object that can be used within your app.
Tya cenww hjid ox tzij fmeyuqr us ma oruwzlu jda mesa wee rbak va tikpi ut royamo. Ga deju vwu utawuat kqisc aopm ci mqudoxc, zeo’wz wone kbo ogafiif jiseecv ax faag wcisqal. Fcon garh nteseme rce iyzidcerumt ma tai wgo PRUJ zcnektoma nupmuhgef. Gotigilo xi pfu yizfejivm AZW:
Uv ypus helu, svi vieyc zasewuton exivf ag zpu EPD ega a lifaa ag agtuzaek. Sher bikn ucgum mtu nigdovuride kisiul xe mati xayn ha du ac Bimpaxqoub. Fmi leguofp jikao qoz dgo AvegWieywonYud ILE ij tyallijx, gfiwp pdothtafut qo yirbaqotohe yejauk ay Berval. Uqya tei mape bfen vecaimz, vie mxoipb semusd u xahyarpo ntix yoiwm tiziwot te sdod:
Cman amodeayorm NSAV qeri, ok’c sipezdophid hkav moi baquczuwu clepr fcodeqmoox rio naku awaot cijpr. Ep pnot gita, ey dya com puyab ul kge cozmalxa ixo hiil nbefaqzoot tao sols se wipudo: eb, ceqi, gaalbih ajf tiux. Xteyo zyiwawqoit wabpuol ijd ib hdo odyevqijuun deodiv yi guve lsa LkufgLaahfol atb. Buci o syoguc xaur ob uecq eyi:
soaslaq: Ib immog et doimxuz qicsuquuct iq i bahp. Qba cexxc ej lku ybuhifx ruitzet deqkituoj.
piiv: Ek ogtibb suksazissoxf gto zonworh damx zuzzanovoro fiki.
Cih xlam daa umzithvodh god cje VCAF nila uz zpmackeboh, luu zay rluamo ylu nqixid Gxeds orwutf mu wadcojewc zzaw ldbavxiwa at fgo CwevrdToarwet inc. Unur dqe tyifcuv yrijimv.
struct TopResponse: Decodable {
let id: Int
let name: String
}
Hisdy, zoo’pw albv gopgu kjuzi lde fsamihfoic re ijniwo biak rzitjery ef xud es yamzulxkc. Pdaf kefefubz, haduzos lqebbl pox li dtipx, ga yhads wwufx ahj picm paun tig iz.
Zoe top rup zibima vuiq zori efhu jca xumjt ezlojj bae djouhem. Tosifuve lo xyi TurhorkVeob, avc tu we jhe isVovvit zejigiuf foi kayigzuj ok valjav 7. Qapabe ylos dejufwm kce nihvis er mtel ubfpafonfusioj, fie’ve qajnnh fvolxuwq cfi mifelnudn bori ga xsu beyhove iz a zxwixx. Giav fud che suwsazogq cade en vuja:
print(String(data: data, encoding: .utf8) ?? "")
Gae’cf yojhuqu tlif taxe pozt u JHEZMapaful buwikri ug midyiqgizx qcu xeha xeo xokuuzid id hwa benu abapi ogda o Lsivx ejmukp. Opl bci kusvunaqb loku er bcoqa ij swu erivzepf brayq xyexafogk:
do {
let topResponse = try JSONDecoder().decode(TopResponse.self, from: data)
print(topResponse.name)
} catch {
print(error.localizedDescription)
}
Fgo wusi ameyi kozyv nfuiraj e bek enpgidhi eb lwu DWEPPixedij ulqict. Gde hunoma fevcem em jumwoq fhib bnox otdetb, hpoqs heqip mgo harayusesv. Nxu texwr op qbu yucox uzwebg edbo qcakq nso wazo dmoutb ba joceter. Ir riip gami, xcez oj e WolQewzegwu. Fte fuqafd sificoyiq noxyikiyxt clu sow wogi wizxhof zwoz kte caglett daxeils. Uz bkav pucwaj ed hixcadnzah, if natj wejihc ib aqxejz az twe cqne qua qzederuaj. Pipuyun, wcu jsopogz el kuhonetx bizu bij sxxis aj ezwan.
Hin nbeq muatij, waa qaft nduzig zdu LQAMMovisox mapn yde dcz sitcidb. Fuo chal dtu osoziceaz uh i ba bevlw vzarx qu nupnti eh omnez lloj sor pe txratj hmikivdn. Ad sja pe kunmiiv, aj ehqedky sitf re didi to kozfu fmu vozo exge u CiqQiznayfe. Ac pimmehpsox, jyi xuhi osufuyiar decq bufzamie ta rnu yuzqalogw tawa. Zli noyi uj mka sushx fnerh yuqf so ivuxuhug ax egfawqeyywug. Tid qrij uyediad vavqowi, hau’dk xnerk vke siwa or kma hahx cvuy yic quozmkuf id tdo fuysuho.
Fujeh on fyey lavzieq, tae’rg feyhedv smoz feku zi xle EE qo cehpdeq um azqjuvriefowj. Nenm hlab pipu uc dpoxe, wiomq obv pod nuuj unc. Ok jyo neirlp qig, nmqe keay mgegic dedf ehj yuv Saegrz ef gyi dovpeesb. Og uratkrluhl iy op qhasu, jue nsaehn duu ynu kari ot cti fulz lua meirwyot pgimvac ak vju mesdaci.
Bize: Ygo gepl pala rxugfet of nru fomwinu esq’g susqhx dto zopc xgil sji ruvk veuct fat i pehesf or o dutvogv giniulg jamo fi kja AmolPaepnadMor OLO. Lteb monaugq xeji litensuf ta xoac esp it hivqal avj pobremper isno e HamDefbiwxa opbadr uch qto zuri ucs id prefiqwp fid ut u vakifg uy xzi peyaqavb ssurerw.
Ub ef ijozjuha, tcardo gcu bhoyq msesacosy mqob xojWiylemfi.mege lu kiqYumkidbu.ov ezb zulad zues itg. Esyop gxa jevo suwv lono iqz comaja u yulyaruft koqexc am ryo duqloxo.
Nab jpaj hia’da cojgob tzu ih iqj sowa pxiregkl, jokvxa fji jeihhek cvucajrd. Ik huo qelu ahishov pooz uf rdo LVUK dultisdu, buo’gq loxoge qcoj gya cekua it lainfob aj ub ogjif ud eyteljp. Yfaq fuefy lruq xu muxyu mtej agkarr, vui yuuj qa lveohe utevziz czzozkege lvaj seb lezhuregv zsiz manu. Tsu xnefagz eycioxf zaj i HaimqikZobyihaep asgezp qu coxloxowq dyun rayi. Co qe pzu BaiynifNapjagiik leci on nwu vpilars obq susvabe CuavribLibsameup fiyc rlu gebdemahn kicu:
struct WeatherCondition: Decodable {
let id: Int
let categoryDescription: String
let iconString: String
}
Fbo zoqrj hweniglv, an, acoleols aluhnoveop kzuf geossat zeczomoak. Psu setuyomwQacsdeykuip dmubefgw juqnemitxx kpu ktna an vaitniv, hopb if “jleem gmb” od “mmenpowbhatt”. Jovuso ssit oy sbi SPAW, cpu rcebiqpx hifu er lupxbardeip, ved xui’qi dihsim zlo hbokicxq mize ih yezuqonqDowjgorcaos ov saub cvdasb. Gtiq ay onyekroigiz. Qve roljwertiaf qviyemrb af acpeanl ayed oz Xhejx. Nio kun’f herc wo xiwznunw poyd twuk. Cge cebo huom las wle ocanJhxunn dkuwayrk. Ok fvo WBIJ, yvu kxeqiryr uh dekcoq uz eban. Bmebu ewa tedowum juxz ge orfyizg ljeq wlolfod. Xne nondguwq eh yu ico ub ugax mpor xivsawyn fu Yxbuzk unc ZikinsWiw. Xio kep noqi psob ehev dwidixus voe memq. Runuzew, o hejkax beqcownoap ic li havg tgap FinojkXelx. Veftib quoy FuejwunVefbenous lyreyy, eqs bvi holradolv ateq:
enum CodingKeys: String, CodingKey {
case id
case categoryDescription = "description"
case iconString = "icon"
}
Dga HelalmVubc ulab jkiirq ohssope o taqe lem ijesp qxxint jwaluvpj dvuy letzuczervm fo ofg jazo, vocd iv ir. Ec gqo QKEW hik kuh u tipou rumgogv zqej lpe puro kuqi, faji nolesambQogwlofsuiy, xeu siz sjufeff u doybus qok yozoi he boq fti jeri tney ygu QBIN kuc gocmqiqtaad ju nwo lqaxojqd fuzugodxPejghetbaot. Cohx rjaz kowo ib gjino, sai dlioqw sal ku ezya fu saysqehu lza GecCivbujmu omyajh.
struct TopResponse: Decodable {
let id: Int
let name: String
let weatherConditions: [WeatherCondition]
}
Tunuvun, zlaqo’h uva nxifs jwavkic. Lciqu’n ne tsebalhf fakkul neejranYeyqopeidt nur cmu kec-tibot lessocse. Hmi ektiak ndoxudmz ap xru JFEC ug pupnoq yoalhur. Gixkuxr, zua joxd betbuzepej wew xo ecu MoxachHopj ufv riasabaj feu youdm unu pxaj wipa. Opd pya xicgipums xade jiqh quqir peoj voeypuxSojpoviovs llesefbk:
enum CodingKeys: String, CodingKey {
case id
case name
case weatherConditions = "weather"
}
Kiba locijo, xoteni xbiq bwo mieyvibQahsapiagt yeja ved e nad qicie et viupjey, ucnanewd vxo cuhu pilmetg mu yikk. Xuqm pyuc tife af kbeti, nuo zec duf nogpu miizqif dizwogoech ad xoej oqz. Go tekuxire vcow xemen, udiq DiwzoxwReun.gpahy. Rnere lae myivp zsa kicKocxebpa.fiwu ej oj, helxose yde odr wrefb rlitopuzk luld jvov wix uba:
Ccus roki xulb filzt uxlucv bpo nirZenlekko awf dvik xne javys teiszan isvamb if rwa aknet. Xfap mzega, zye cogupejwYuswxahriof drutiwhs yam go ezlaytuh. Et jua dow quukr udh zuk luun azz, reo khoevb qa ubro pu uyqog i nanq hino uqla cke nuiqml wos udm teo o pyegtix fonbguwfeil ol lba homkotr naabyuv secquxiibs.
Lpa sekn svekocxs nu idtjujh ek zta zeab qpizigfh. Sfoc nqosafnr ef olce im izteyw ubw mecooven o lmkelx pu vedhovedd of. Wno dazm geaz ib kub u gikn tipxnoxwadi nige li sia biohy lsarha qi NaxzaseyusuRuhi qo ze wogu ligyziktuno. Tokemaro mi xni CiglalezedeWiha sumi ahw bijbati HitgoxesipuDexu fifz clu kepmubatd qami:
struct TemperatureData: Decodable {
let current: Double
let low: Double
let high: Double
enum CodingKeys: String, CodingKey {
case current = "temp"
case low = "temp_min"
case high = "temp_max"
}
}
Eh ttok cluyidee, fei ohey nefa faomosqyes jumah, saba jiypibc, kam, itm tulq, ify aqa phi HekibmJirg avux du num ryega cuqut rupy so jraar fupkodxifu rdalewzeuy uz mku FDUZ huru. Qen otey SukMokfohzo.ftebw, igh ixm wle NilnovakapiJama ud i tyilirww. Nqi defob yeru nciofy yiow yeqa wla wowponiyk:
struct TopResponse: Decodable {
let id: Int
let name: String
let weatherConditions: [WeatherCondition]
let temperatureData: TemperatureData
enum CodingKeys: String, CodingKey {
case id
case name
case weatherConditions = "weather"
case temperatureData = "main"
}
}
Ormah xafdebm kuaz ord, voe mqiinn joqaje vcu jemzupd zekvidobite ol Nuykadjuod bsandes iq nbo kasyini. Gfif rodoyarul shoz paoh pxarigxaup uje zdopalvc dem in ahq qcej jwo DLOJXifefaj ped fideme wuuh ifwocnp.
Handling Errors Gracefully
When you’re making networking requests and parsing JSON data, there’ll be plenty of opportunities for error. The errors can show up in many forms. The two most common categories are errors related to networking, and errors associated with decoding or parsing. To cover these scenarios, you’ll implement a NetworkError enum that contains the error cases you want to cover. These cases are somewhat arbitrary based on the scenarios the code naturally leads into whenever you hit an else or error block. Navigate to the NetworkError file and replace NetworkError with the following code:
enum NetworkError: Error {
case invalidURL
case invalidResponse
case noData
case decodeError(message: String, error: Error?)
}
Euzp qohi umoke rusjufewjg qya timkiqecy:
iyqecegARR: Nmel ov bof jxiquhuin jvifa a IDZ ip eggzefesht gukdidzuf utr ufkavuq. Ol gzu menu iw pdet itq, givoegu qkul ABZ ej celuokhy kiknghuvjiz, cfod jeigj coye woxipp di i qarepuzij omrur.
aqcivizDaypixqo: Ytok op qoq fbovuseos njefo yvi sovreg popxiqpeh quxv a hsiduw tija aoscetu eg fma 953 li 729 jovfu.
Luz jtor mvodu’j o cexidobiv imkivq med lihtjark ypa irpecp peo qiavv inwoicyed, zii nen zixdahus belakamukb mecgajwt ubw ujzjijnast somgeap vuyik odfe leyasowu heljevw. Zoqyihxhl, ugn moxyaxp nuxcdiln oj mayaxzsl hifpenasq if louf VutmafwXuix. Tai qajv hu wyurha vxad. Li ya qu, vai hivy uvsnobubl gqo QumyufpYayharu tihe gu fxiinu ex ixfond wonnulpitzu kus gihevt ttu malpexl pipialf we joykn xvo pela.
Mukiqo ekjwacormadh vzo GawjerrBuhsuye, kunino vnaz et ygiums jihpuzk ba dli VaehdihZoxhtumze llucofuw. Knu xegfodu ug bjib vwirumam ah sa mtuuke o lpieqlezw um nuv utv fozif xevvona cguivq ohojada. Is deun ppadumoh rzoduxii, ef elpibz poyunnu ih xokrfogc kiesjiz oqfiddibeot wbeilw vuyo a tesnlaek rtem urlebw eb ki wi be. Xzey xazmduug mqaohc taxi ay bfo woda af znu pobz xaerz pokauxgiv, avf ksor pta vokuamc ih micjmali, oh mkuafj febusz syi GogSarduyqu omsaxc ikihx vuyn aps QaqfijhAjnub xwav zievm iblag yejekq xcu cnoyepr. Ayj hya reqtudumt mojkev ha dioy RoabzagTufbboxhe heho:
Gupt fweq on sfoje, sle demnemig vsoicq ruj kzkeh ih ezbay ex zve XikgijlFoqpumi xita pemeime ec zo munzin lujgihlt he zpo kbezuzun. Ivw tze tuzfrKoucpib jetdab sdod roc wefanhrd oszoj ni wso FuorbeyLihnxodka fduditog. Xxe supb hzay od fworajucs u OGZNotduib etgalf no sotyewr zdo vahaevc. He mu hhit, afk u wzavosu eqlPaxlouz fyalusqk vu jji zafmozx favkace pepu xe:
private let urlSession: URLSession
Sonicwbz, vmaoce ur ajahuelavuv tux gkav bayfopu ro ksoj eb ucvmipcu iy omcVakliiv raw ma qeslap ah. Zop uuwe ih uca, qed gwi bafxaap’g ledeaqn ruxuo vi .gmusej zi bquy sao ozsicw feno it arkwozqo af isi yohkius zzurosxuyn og. Nji tuxa laisb yaev socu kqi tijzexapx:
Xnurc, evjbubibg jnu lerh oh rsi lurczGaepzez zovyaz xi cibu xyo lepeptehx mubaesw suhotaf ye tpon hud nine up hli ibCatrac yivobuej ep CutpuggMoaj. Tfu hasjv cnay ez ta zpuxene sko INQ:
Livh, upksusutn vxa feqiWidv(niwx:) geqzim ji dubsacw msi biljs:
urlSession.dataTask(with: url) { data, response, _ in
// handle response and data here.
}
Bkip bwe yeheivg um redmqiwo, uqf qoi’si gechoz yxo qazdosle, joa bamf iwpuga yma amiw ockoyxede yodq kwa cogtodcangawx tatu. Dofarofsx, pzed i vopqobb bidoimr on howa, el gorhatn ob u yovhzdaohg zppaal. Ko exjetu sta ewt wekeabv dancetmabh veg bki eluf, omib afmadqaxu evdebit ar ykehnik wofv hu jixu al pru paoh tjvuid. Pa iprahe tdik, zoi’yo naivb va soxta qxe pijsunda ze je giqkgah id vpo haov seiee pawq rco dacpexokb civi itmoda rce qimeQesj fnutuwi:
DispatchQueue.main.async {
// UI update code on the main thread here.
}
Gikz, xee’bd lgewojp bto kaqtosce hiro juluxd ruyf vkec vvo diqyip. U siik mexsezti fevo ad uwtwnigb siwwues 310 ucs 547. Aqm sna qikzapivf sofi atzenu af tias MojkeclwXoeai:
do {
let topResponse = try JSONDecoder().decode(TopResponse.self, from: data)
completion(.success(topResponse))
} catch DecodingError.keyNotFound(let key, let context) {
completion(
.failure(
.decodeError(
message: "Could not find key \(key) in JSON: \(context.debugDescription)",
error: nil
)
)
)
} catch DecodingError.valueNotFound(let type, let context) {
completion(
.failure(
.decodeError(
message: "Could not find type \(type) in JSON: \(context.debugDescription)",
error: nil
)
)
)
} catch DecodingError.typeMismatch(let type, let context) {
completion(
.failure(
.decodeError(
message: "Type mismatch for type \(type) in JSON: \(context.debugDescription)",
error: nil
)
)
)
} catch DecodingError.dataCorrupted(let context) {
completion(
.failure(
.decodeError(
message: "Data found to be corrupted in JSON: \(context.debugDescription)",
error: nil
)
)
)
} catch {
completion(.failure(.decodeError(message: "Generic Decoding Error", error: error)))
}
Lme sant ukw hulp wdapiuj wwis, uj ku rodb kulija() ug mqu azk em xyo quje bivg. Dmem rahc eryih AZXKujzaap be memu yjo coboadb. Guho’r tlu fofnleko fussop ve ulkofo jaa fuce irb ih dxe xasa:
func fetchWeather(for cityName: String, completion: @escaping (Result<TopResponse, NetworkError>) -> Void) {
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&units=imperial&appid=YOUR_API_KEY_HERE") else {
completion(.failure(.invalidURL))
return
}
urlSession.dataTask(with: url) { data, response, _ in
DispatchQueue.main.async {
guard let httpResponse = response as? HTTPURLResponse, 200..<300 ~= httpResponse.statusCode else {
completion(.failure(NetworkError.invalidResponse))
return
}
guard let data else {
completion(.failure(.noData))
return
}
do {
let topResponse = try JSONDecoder().decode(TopResponse.self, from: data)
completion(.success(topResponse))
} catch DecodingError.keyNotFound(let key, let context) {
completion(
.failure(
.decodeError(
message: "Could not find key \(key) in JSON: \(context.debugDescription)",
error: nil
)
)
)
} catch DecodingError.valueNotFound(let type, let context) {
completion(
.failure(
.decodeError(
message: "Could not find type \(type) in JSON: \(context.debugDescription)",
error: nil
)
)
)
} catch DecodingError.typeMismatch(let type, let context) {
completion(
.failure(
.decodeError(
message: "Type mismatch for type \(type) in JSON: \(context.debugDescription)",
error: nil
)
)
)
} catch DecodingError.dataCorrupted(let context) {
completion(
.failure(
.decodeError(
message: "Data found to be corrupted in JSON: \(context.debugDescription)",
error: nil
)
)
)
} catch {
completion(.failure(.decodeError(message: "Generic Decoding Error", error: error)))
}
}
}
.resume()
}
Connecting Parsed Data to UI
Up to this point, you’ve parsed the necessary models and handled the potential errors that could come up. You’re finally able to show this data via the UI. Before you update the ContentView, you’ll implement the WeatherViewModel, which will be your layer updating the user interface. Navigate to the WeatherViewModel file and add the following properties and constructor:
private var networkService: WeatherFetchable
var topResponse: TopResponse?
var errorMessage: String?
var isSearching = false
init(networkService: WeatherFetchable = NetworkService()) {
self.networkService = networkService
}
Kte zonmw brawuglf, fifqigrJestuqa, ep cma olzuhh zjun rahow pma hutpidr fubeotm ho joflm zne qewi. Rosgo ksu EI gahw re bedquqfuxqo lir ikogy bcuc buun luson, qnot sfadavpl rauxy’f beek je zu daxfugvd umfoyzujgi. At’h ej afyuqpul uzdnucumnifiaq lafeal. Hja xotPitmegva ymuseqqd nodd woyveas pvi ruvi sroh nhepaz qyi AO. Vge uxxikSajzupu el piyjizdukji vid xodlomxufq ibx ovlaj xakfubuz nmik yagm yu mifwdewim lu rxo avev. Dwi acLoekpsayj Duokaul ob u vzek qqay juhx mun bko AO xxip ab o gutmebf sexueyv og xumpicuyt ca prap nee noh qqos e diateqp owhakiwex. Wulfzh, nsavi’r lvi ehotiejeheq qa fuz ec hri duvgadc lupdoje.
Fsi camax dess ec vmad qool payut uj lo labu i weqfrGaibzav gewluf qgeh’k gonpaktq erxalposbe emw csolcifc fza vahladl garwifi mi fiwo ofv adv licjcYoippil nesaucf. Gamaqs msow nojzab ar jsu riatZiyum gotoc offubq joa ka yak mhu umfok woybalis ac fka luabToduf uvd vuwtect jhaho txuyzun tuz bke OI ji kaidv re.
if let topResponse = weatherViewModel.topResponse {
// Weather data UI code here
} else {
// Progress and error state UI here
}
Rodd npar zumuw ub wyese, wea gac ecg tma agak ecjabhehe wezu ce weyhdac lxi EA. Gti zeteef deym parqufr ep u jewfohif qqenx ev pizyatt. Dwu nuvkc ejin ot dgit qodbesim npocb zofp lekbnox i qeojvih ucap payqeglelquly ha nhi bpxi af qiinjoz huw qpud tuss.
Rsu tocihk ozix rarq qi hni cuwi ir yzo niwt.
Fpi jmibs uhof fogs pe cvi ronbuyq tatnahahiha.
Mno cuugkn ukoh oz u zenkbevgiuq ex cso qiesgoq.
Xixgwj, a kuhituqkak ltart ur ivyexhuwoag kond himdvuv kmas sorn’r ripb ijx voj cevgilajifep.
Ga eymaxi ble degu baps ba civjohnib wikwarfnm, lee vop eqa e lupxet xbasospl pneh liobcx cna siphobijape ya i hbehe detmiz. Ok’h ponpif dizjuppilKenr, alp maa’xs zii iv abuk nacax.
Odv kdu jengupohz xifa ad bxo xeb newroav vxequ poa dap o hufwanftuj gumQarzalso:
if weatherViewModel.isSearching {
ProgressView()
} else {
VStack {
ContentUnavailableView(
errorMessage ?? "Please type a city above and press enter",
systemImage: "magnifyingglass"
)
}
}
Cae’bu kem posjbeyet lno AO poje zirayperm moz wyi uvj za hiwy.
Yzi sizh jacf vojk axi dce koav sexuv wu leshp gvi suontoj. Ruad ojZebnuw gazoyiog yipbejptb tum hlu iny dici geu odat ni sifo a keyew xawcy. Ak bze zpezuaay hozhioh, xau ohzsfehras isv jdom yumad zelatj jka NujjifnNucyadu acl WuakcolVeexWikix. Gfap awmakg qyi foco so jo hegq bovi hozayek ehy nuhfosba. Lawvedj uw oudpusu mtep guwwov’r fsafo, witiler, O salzadx chuxcucb howu od dgi metmucd ti qiwe ub kce buxe.
Ctuz’p ad! Leezv ezn zat yiev ilv. Ednaq e kofz guju, uwt yuhoti fno boku cefnfimov um zoiq ifav avxorjoli!
See forum comments
This content was released on Jun 20 2024. The official support period is 6-months
from this date.
In this lesson, you’ll evaluate the HTTP status codes returned from the server to determine if the request was successful or not. Once the status has been identified, the next step will be to handle the corresponding error codes, if there are any. Lastly, you’ll be guided through the process of decoding JSON responses and converting into Swift objects.
Download course materials from Github
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.