[{"data":1,"prerenderedAt":2712},["ShallowReactive",2],{"Categories":3,"NavIndexCategoriesCountFooter":203,"content-\u002F2020\u002F03\u002F30\u002Faccount-view\u002F":204},[4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,68,70,71,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202],{"category":5},"System Administration",{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":27},"Software Development",{"category":5},{"category":5},{"category":5},{"category":5},{"category":27},{"category":27},{"category":5},{"category":5},{"category":5},{"category":27},{"category":5},{"category":5},{"category":5},{"category":27},{"category":27},{"category":27},{"category":27},{"category":5},{"category":5},{"category":5},{"category":27},{"category":27},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":5},{"category":27},{"category":5},{"category":5},{"category":27},{"category":27},{"category":27},{"category":27},{"category":5},{"category":27},{"category":27},{"category":67},"Drones & RC",{"category":69},"DIY Projects",{"category":67},{"category":72},"Photography",{"category":69},{"category":69},{"category":69},{"category":67},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":69},{"category":67},{"category":69},{"category":69},{"category":67},{"category":67},{"category":72},{"category":72},{"category":72},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":5},{"category":5},{"category":72},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":5},{"category":67},{"category":67},{"category":72},{"category":72},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":67},{"category":72},{"category":67},{"category":138},"3D Printing - Laser Cutting - CNC",{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":138},{"category":5},{"category":138},{"category":27},{"category":27},{"category":138},{"category":138},{"category":72},{"category":158},"Photography,3D Printing - Laser Cutting - CNC",{"category":27},{"category":27},{"category":69},{"category":27},{"category":27},{"category":27},{"category":27},{"category":5},{"category":67},{"category":5},{"category":5},{"category":27},{"category":27},{"category":27},{"category":27},{"category":27},{"category":69},{"category":27},{"category":27},{"category":27},{"category":27},{"category":181},"Home Assistant",{"category":181},{"category":72},{"category":27},{"category":27},{"category":72},{"category":138},{"category":5},{"category":72},{"category":72},{"category":138},{"category":27},{"category":181},{"category":181},{"category":72},{"category":72},{"category":72},{"category":72},{"category":72},{"category":72},{"category":72},{"category":72},191,{"id":205,"title":206,"body":207,"category":2696,"date":2697,"description":213,"embedImage":2696,"extension":2698,"image":2000,"intro":2699,"meta":2700,"navigation":547,"path":2701,"seo":2702,"series":2703,"sitemap":2704,"stem":2705,"tags":2706,"__hash__":2711},"content\u002F2020\u002F03\u002F30\u002Faccount-view.md","Account View",{"type":208,"value":209,"toc":2684},"minimark",[210,214,217,220,225,228,231,244,256,259,315,318,321,430,435,438,441,444,725,729,732,1175,1177,1181,1184,1187,1300,1303,1485,1488,1490,1494,1497,1505,1509,1512,1989,1992,1995,2001,2004,2245,2248,2251,2387,2390,2654,2656,2660,2663,2666,2668,2680],[211,212,213],"p",{},"The app so far has the ability to get an authentication token.",[211,215,216],{},"The next step is to actually use it.",[218,219],"hr",{},[221,222,224],"h2",{"id":223},"account-information","Account Information",[211,226,227],{},"We need to fetch the top level account overview.",[211,229,230],{},"This is a GET request with the following headers",[232,233,234,238,241],"ul",{},[235,236,237],"li",{},"Accept: application\u002Fjson",[235,239,240],{},"Authorization: Bearer AUTH_TOKEN",[235,242,243],{},"customerId: USER_ID",[211,245,246,247,251,252,255],{},"where ",[248,249,250],"code",{},"AUTH_TOKEN"," is the token from the auth call and ",[248,253,254],{},"USER_ID"," is the userId from the config object.",[211,257,258],{},"The format of the response is:",[260,261,266],"pre",{"className":262,"code":263,"language":264,"meta":265,"style":265},"language-json shiki shiki-themes github-dark","{\n  \"availableItems\": Int,\n  \"items\": [Account]\n}\n","json","",[248,267,268,277,294,309],{"__ignoreMap":265},[269,270,273],"span",{"class":271,"line":272},"line",1,[269,274,276],{"class":275},"s95oV","{\n",[269,278,280,284,287,291],{"class":271,"line":279},2,[269,281,283],{"class":282},"sDLfK","  \"availableItems\"",[269,285,286],{"class":275},": ",[269,288,290],{"class":289},"s6RL2","Int",[269,292,293],{"class":275},",\n",[269,295,297,300,303,306],{"class":271,"line":296},3,[269,298,299],{"class":282},"  \"items\"",[269,301,302],{"class":275},": [",[269,304,305],{"class":289},"Account",[269,307,308],{"class":275},"]\n",[269,310,312],{"class":271,"line":311},4,[269,313,314],{"class":275},"}\n",[211,316,317],{},"There are some further error fields available. To be honest - for this small app - all we need is the items field.",[211,319,320],{},"An account looks like this:",[260,322,324],{"className":262,"code":323,"language":264,"meta":265,"style":265},"{\n  \"accountId\": \"String\",\n  \"accountNumber\": \"String\",\n  \"ownerCustomerId\": \"String\",\n  \"name\": \"String\",\n  \"accountType\": \"String\",\n  \"available\": Double,\n  \"balance\": Double,\n  \"creditLimit\": Double\n}\n",[248,325,326,330,343,354,365,377,389,402,414,425],{"__ignoreMap":265},[269,327,328],{"class":271,"line":272},[269,329,276],{"class":275},[269,331,332,335,337,341],{"class":271,"line":279},[269,333,334],{"class":282},"  \"accountId\"",[269,336,286],{"class":275},[269,338,340],{"class":339},"sU2Wk","\"String\"",[269,342,293],{"class":275},[269,344,345,348,350,352],{"class":271,"line":296},[269,346,347],{"class":282},"  \"accountNumber\"",[269,349,286],{"class":275},[269,351,340],{"class":339},[269,353,293],{"class":275},[269,355,356,359,361,363],{"class":271,"line":311},[269,357,358],{"class":282},"  \"ownerCustomerId\"",[269,360,286],{"class":275},[269,362,340],{"class":339},[269,364,293],{"class":275},[269,366,368,371,373,375],{"class":271,"line":367},5,[269,369,370],{"class":282},"  \"name\"",[269,372,286],{"class":275},[269,374,340],{"class":339},[269,376,293],{"class":275},[269,378,380,383,385,387],{"class":271,"line":379},6,[269,381,382],{"class":282},"  \"accountType\"",[269,384,286],{"class":275},[269,386,340],{"class":339},[269,388,293],{"class":275},[269,390,392,395,397,400],{"class":271,"line":391},7,[269,393,394],{"class":282},"  \"available\"",[269,396,286],{"class":275},[269,398,399],{"class":289},"Double",[269,401,293],{"class":275},[269,403,405,408,410,412],{"class":271,"line":404},8,[269,406,407],{"class":282},"  \"balance\"",[269,409,286],{"class":275},[269,411,399],{"class":289},[269,413,293],{"class":275},[269,415,417,420,422],{"class":271,"line":416},9,[269,418,419],{"class":282},"  \"creditLimit\"",[269,421,286],{"class":275},[269,423,424],{"class":289},"Double\n",[269,426,428],{"class":271,"line":427},10,[269,429,314],{"class":275},[431,432,434],"h3",{"id":433},"model","Model",[211,436,437],{},"So - we'll start modelling this in a service file with model and method - similar to the TokenService. Create a new file called AccountService.swift.",[211,439,440],{},"At the top we're going to need to add an import for Alamofire.",[211,442,443],{},"Then we can model the structure we want. Here we will model the entire account object but just pull out the items list from the containing response:",[260,445,449],{"className":446,"code":447,"language":448,"meta":265,"style":265},"language-swift shiki shiki-themes github-dark","struct Account : Decodable {\n    let accountId: String\n    let accountNumber: String\n    let ownerCustomerId: String\n    let name: String\n    let accountType: String\n    let available: Double\n    let balance: Double\n    let creditLimit: Double\n\n    enum CodingKeys: String, CodingKey {\n        case accountId\n        case accountNumber\n        case ownerCustomerId\n        case name\n        case accountType\n        case available\n        case balance\n        case creditLimit\n    }\n\n}\n\nstruct Accounts : Decodable {\n    let accounts: [Account]\n\n    enum CodingKeys: String, CodingKey {\n        case accounts = \"items\"\n    }\n}\n","swift",[248,450,451,469,480,489,498,507,516,525,534,543,549,571,580,588,596,604,612,620,628,636,642,647,652,657,671,679,684,701,715,720],{"__ignoreMap":265},[269,452,453,457,461,464,467],{"class":271,"line":272},[269,454,456],{"class":455},"snl16","struct",[269,458,460],{"class":459},"svObZ"," Account",[269,462,463],{"class":275}," : ",[269,465,466],{"class":459},"Decodable ",[269,468,276],{"class":275},[269,470,471,474,477],{"class":271,"line":279},[269,472,473],{"class":455},"    let",[269,475,476],{"class":275}," accountId: ",[269,478,479],{"class":282},"String\n",[269,481,482,484,487],{"class":271,"line":296},[269,483,473],{"class":455},[269,485,486],{"class":275}," accountNumber: ",[269,488,479],{"class":282},[269,490,491,493,496],{"class":271,"line":311},[269,492,473],{"class":455},[269,494,495],{"class":275}," ownerCustomerId: ",[269,497,479],{"class":282},[269,499,500,502,505],{"class":271,"line":367},[269,501,473],{"class":455},[269,503,504],{"class":275}," name: ",[269,506,479],{"class":282},[269,508,509,511,514],{"class":271,"line":379},[269,510,473],{"class":455},[269,512,513],{"class":275}," accountType: ",[269,515,479],{"class":282},[269,517,518,520,523],{"class":271,"line":391},[269,519,473],{"class":455},[269,521,522],{"class":275}," available: ",[269,524,424],{"class":282},[269,526,527,529,532],{"class":271,"line":404},[269,528,473],{"class":455},[269,530,531],{"class":275}," balance: ",[269,533,424],{"class":282},[269,535,536,538,541],{"class":271,"line":416},[269,537,473],{"class":455},[269,539,540],{"class":275}," creditLimit: ",[269,542,424],{"class":282},[269,544,545],{"class":271,"line":427},[269,546,548],{"emptyLinePlaceholder":547},true,"\n",[269,550,552,555,558,560,563,566,569],{"class":271,"line":551},11,[269,553,554],{"class":455},"    enum",[269,556,557],{"class":459}," CodingKeys",[269,559,286],{"class":275},[269,561,562],{"class":282},"String",[269,564,565],{"class":275},", ",[269,567,568],{"class":459},"CodingKey ",[269,570,276],{"class":275},[269,572,574,577],{"class":271,"line":573},12,[269,575,576],{"class":455},"        case",[269,578,579],{"class":282}," accountId\n",[269,581,583,585],{"class":271,"line":582},13,[269,584,576],{"class":455},[269,586,587],{"class":282}," accountNumber\n",[269,589,591,593],{"class":271,"line":590},14,[269,592,576],{"class":455},[269,594,595],{"class":282}," ownerCustomerId\n",[269,597,599,601],{"class":271,"line":598},15,[269,600,576],{"class":455},[269,602,603],{"class":282}," name\n",[269,605,607,609],{"class":271,"line":606},16,[269,608,576],{"class":455},[269,610,611],{"class":282}," accountType\n",[269,613,615,617],{"class":271,"line":614},17,[269,616,576],{"class":455},[269,618,619],{"class":282}," available\n",[269,621,623,625],{"class":271,"line":622},18,[269,624,576],{"class":455},[269,626,627],{"class":282}," balance\n",[269,629,631,633],{"class":271,"line":630},19,[269,632,576],{"class":455},[269,634,635],{"class":282}," creditLimit\n",[269,637,639],{"class":271,"line":638},20,[269,640,641],{"class":275},"    }\n",[269,643,645],{"class":271,"line":644},21,[269,646,548],{"emptyLinePlaceholder":547},[269,648,650],{"class":271,"line":649},22,[269,651,314],{"class":275},[269,653,655],{"class":271,"line":654},23,[269,656,548],{"emptyLinePlaceholder":547},[269,658,660,662,665,667,669],{"class":271,"line":659},24,[269,661,456],{"class":455},[269,663,664],{"class":459}," Accounts",[269,666,463],{"class":275},[269,668,466],{"class":459},[269,670,276],{"class":275},[269,672,674,676],{"class":271,"line":673},25,[269,675,473],{"class":455},[269,677,678],{"class":275}," accounts: [Account]\n",[269,680,682],{"class":271,"line":681},26,[269,683,548],{"emptyLinePlaceholder":547},[269,685,687,689,691,693,695,697,699],{"class":271,"line":686},27,[269,688,554],{"class":455},[269,690,557],{"class":459},[269,692,286],{"class":275},[269,694,562],{"class":282},[269,696,565],{"class":275},[269,698,568],{"class":459},[269,700,276],{"class":275},[269,702,704,706,709,712],{"class":271,"line":703},28,[269,705,576],{"class":455},[269,707,708],{"class":282}," accounts",[269,710,711],{"class":455}," =",[269,713,714],{"class":339}," \"items\"\n",[269,716,718],{"class":271,"line":717},29,[269,719,641],{"class":275},[269,721,723],{"class":271,"line":722},30,[269,724,314],{"class":275},[431,726,728],{"id":727},"service-call","Service call",[211,730,731],{},"Let's add a method to do this. It will take a config object and the current token and return an optional Account (if we get a response and if we find one with a matching account number). It will also callback when complete:",[260,733,735],{"className":446,"code":734,"language":448,"meta":265,"style":265},"    public static func getAccountDetails(config: Config, token: String, onComplete: @escaping (_ account: Account?) -> Void) {\n        let decoder = JSONDecoder()\n\n        \u002F\u002F Set up the headers for token based bearer auth.\n        let headers: HTTPHeaders = [\n            \"Authorization\": \"Bearer \\(token)\",\n            \"Accept\": \"application\u002Fjson\",\n            \"customerId\": config.userId\n        ]\n\n        \u002F\u002F Call the service\n        let request = AF.request(\"https:\u002F\u002Fapi.sbanken.no\u002Fexec.bank\u002Fapi\u002Fv1\u002Faccounts\u002F\",\n                                 method: .get,\n                                 headers: headers)\n\n        \u002F\u002F Decode the response\n        request.responseDecodable(of: Accounts.self, decoder: decoder) { (response) in\n            if let error = response.error {\n                print(\"Unable to fetch accounts \\(response) \\(error.localizedDescription)\")\n\n                onComplete(nil)\n\n                return\n            }\n\n            guard let account = response.value?.accounts.filter({ (account) -> Bool in\n                account.accountNumber == config.accountNr\n            }).first else {\n                print(\"Unable to find account\")\n\n                onComplete(nil)\n\n                return\n            }\n\n            onComplete(account)\n        }\n    }\n",[248,736,737,795,812,816,822,834,853,865,875,880,884,889,911,919,927,931,936,966,988,1015,1019,1031,1035,1040,1045,1049,1085,1096,1109,1120,1124,1135,1140,1145,1150,1155,1164,1170],{"__ignoreMap":265},[269,738,739,742,745,748,751,754,757,760,763,765,767,769,772,774,777,780,783,786,789,792],{"class":271,"line":272},[269,740,741],{"class":455},"    public",[269,743,744],{"class":455}," static",[269,746,747],{"class":455}," func",[269,749,750],{"class":459}," getAccountDetails",[269,752,753],{"class":275},"(",[269,755,756],{"class":459},"config",[269,758,759],{"class":275},": Config, ",[269,761,762],{"class":459},"token",[269,764,286],{"class":275},[269,766,562],{"class":282},[269,768,565],{"class":275},[269,770,771],{"class":459},"onComplete",[269,773,286],{"class":275},[269,775,776],{"class":455},"@escaping",[269,778,779],{"class":275}," (_ account: Account",[269,781,782],{"class":455},"?",[269,784,785],{"class":275},") ",[269,787,788],{"class":455},"->",[269,790,791],{"class":282}," Void",[269,793,794],{"class":275},") {\n",[269,796,797,800,803,806,809],{"class":271,"line":279},[269,798,799],{"class":455},"        let",[269,801,802],{"class":275}," decoder ",[269,804,805],{"class":455},"=",[269,807,808],{"class":282}," JSONDecoder",[269,810,811],{"class":275},"()\n",[269,813,814],{"class":271,"line":296},[269,815,548],{"emptyLinePlaceholder":547},[269,817,818],{"class":271,"line":311},[269,819,821],{"class":820},"sAwPA","        \u002F\u002F Set up the headers for token based bearer auth.\n",[269,823,824,826,829,831],{"class":271,"line":367},[269,825,799],{"class":455},[269,827,828],{"class":275}," headers: HTTPHeaders ",[269,830,805],{"class":455},[269,832,833],{"class":275}," [\n",[269,835,836,839,842,845,848,851],{"class":271,"line":379},[269,837,838],{"class":339},"            \"Authorization\"",[269,840,841],{"class":455},":",[269,843,844],{"class":339}," \"Bearer ",[269,846,847],{"class":339},"\\(token)",[269,849,850],{"class":339},"\"",[269,852,293],{"class":275},[269,854,855,858,860,863],{"class":271,"line":391},[269,856,857],{"class":339},"            \"Accept\"",[269,859,841],{"class":455},[269,861,862],{"class":339}," \"application\u002Fjson\"",[269,864,293],{"class":275},[269,866,867,870,872],{"class":271,"line":404},[269,868,869],{"class":339},"            \"customerId\"",[269,871,841],{"class":455},[269,873,874],{"class":275}," config.userId\n",[269,876,877],{"class":271,"line":416},[269,878,879],{"class":275},"        ]\n",[269,881,882],{"class":271,"line":427},[269,883,548],{"emptyLinePlaceholder":547},[269,885,886],{"class":271,"line":551},[269,887,888],{"class":820},"        \u002F\u002F Call the service\n",[269,890,891,893,896,898,901,904,906,909],{"class":271,"line":573},[269,892,799],{"class":455},[269,894,895],{"class":275}," request ",[269,897,805],{"class":455},[269,899,900],{"class":275}," AF.",[269,902,903],{"class":282},"request",[269,905,753],{"class":275},[269,907,908],{"class":339},"\"https:\u002F\u002Fapi.sbanken.no\u002Fexec.bank\u002Fapi\u002Fv1\u002Faccounts\u002F\"",[269,910,293],{"class":275},[269,912,913,916],{"class":271,"line":582},[269,914,915],{"class":282},"                                 method",[269,917,918],{"class":275},": .get,\n",[269,920,921,924],{"class":271,"line":590},[269,922,923],{"class":282},"                                 headers",[269,925,926],{"class":275},": headers)\n",[269,928,929],{"class":271,"line":598},[269,930,548],{"emptyLinePlaceholder":547},[269,932,933],{"class":271,"line":606},[269,934,935],{"class":820},"        \u002F\u002F Decode the response\n",[269,937,938,941,944,946,949,952,955,957,960,963],{"class":271,"line":614},[269,939,940],{"class":275},"        request.",[269,942,943],{"class":282},"responseDecodable",[269,945,753],{"class":275},[269,947,948],{"class":282},"of",[269,950,951],{"class":275},": Accounts.",[269,953,954],{"class":455},"self",[269,956,565],{"class":275},[269,958,959],{"class":282},"decoder",[269,961,962],{"class":275},": decoder) { (response) ",[269,964,965],{"class":455},"in\n",[269,967,968,971,974,977,979,982,985],{"class":271,"line":622},[269,969,970],{"class":455},"            if",[269,972,973],{"class":455}," let",[269,975,976],{"class":275}," error ",[269,978,805],{"class":455},[269,980,981],{"class":275}," response.",[269,983,984],{"class":282},"error",[269,986,987],{"class":275}," {\n",[269,989,990,993,995,998,1001,1004,1007,1010,1012],{"class":271,"line":630},[269,991,992],{"class":282},"                print",[269,994,753],{"class":275},[269,996,997],{"class":339},"\"Unable to fetch accounts ",[269,999,1000],{"class":339},"\\(response)",[269,1002,1003],{"class":339}," \\(error.",[269,1005,1006],{"class":275},"localizedDescription",[269,1008,1009],{"class":339},")",[269,1011,850],{"class":339},[269,1013,1014],{"class":275},")\n",[269,1016,1017],{"class":271,"line":638},[269,1018,548],{"emptyLinePlaceholder":547},[269,1020,1021,1024,1026,1029],{"class":271,"line":644},[269,1022,1023],{"class":282},"                onComplete",[269,1025,753],{"class":275},[269,1027,1028],{"class":282},"nil",[269,1030,1014],{"class":275},[269,1032,1033],{"class":271,"line":649},[269,1034,548],{"emptyLinePlaceholder":547},[269,1036,1037],{"class":271,"line":654},[269,1038,1039],{"class":455},"                return\n",[269,1041,1042],{"class":271,"line":659},[269,1043,1044],{"class":275},"            }\n",[269,1046,1047],{"class":271,"line":673},[269,1048,548],{"emptyLinePlaceholder":547},[269,1050,1051,1054,1056,1059,1061,1063,1066,1068,1071,1074,1077,1079,1082],{"class":271,"line":681},[269,1052,1053],{"class":455},"            guard",[269,1055,973],{"class":455},[269,1057,1058],{"class":275}," account ",[269,1060,805],{"class":455},[269,1062,981],{"class":275},[269,1064,1065],{"class":282},"value",[269,1067,782],{"class":455},[269,1069,1070],{"class":275},".accounts.",[269,1072,1073],{"class":282},"filter",[269,1075,1076],{"class":275},"({ (account) ",[269,1078,788],{"class":455},[269,1080,1081],{"class":282}," Bool",[269,1083,1084],{"class":455}," in\n",[269,1086,1087,1090,1093],{"class":271,"line":686},[269,1088,1089],{"class":275},"                account.accountNumber ",[269,1091,1092],{"class":455},"==",[269,1094,1095],{"class":275}," config.accountNr\n",[269,1097,1098,1101,1104,1107],{"class":271,"line":703},[269,1099,1100],{"class":275},"            }).",[269,1102,1103],{"class":282},"first",[269,1105,1106],{"class":455}," else",[269,1108,987],{"class":275},[269,1110,1111,1113,1115,1118],{"class":271,"line":717},[269,1112,992],{"class":282},[269,1114,753],{"class":275},[269,1116,1117],{"class":339},"\"Unable to find account\"",[269,1119,1014],{"class":275},[269,1121,1122],{"class":271,"line":722},[269,1123,548],{"emptyLinePlaceholder":547},[269,1125,1127,1129,1131,1133],{"class":271,"line":1126},31,[269,1128,1023],{"class":282},[269,1130,753],{"class":275},[269,1132,1028],{"class":282},[269,1134,1014],{"class":275},[269,1136,1138],{"class":271,"line":1137},32,[269,1139,548],{"emptyLinePlaceholder":547},[269,1141,1143],{"class":271,"line":1142},33,[269,1144,1039],{"class":455},[269,1146,1148],{"class":271,"line":1147},34,[269,1149,1044],{"class":275},[269,1151,1153],{"class":271,"line":1152},35,[269,1154,548],{"emptyLinePlaceholder":547},[269,1156,1158,1161],{"class":271,"line":1157},36,[269,1159,1160],{"class":282},"            onComplete",[269,1162,1163],{"class":275},"(account)\n",[269,1165,1167],{"class":271,"line":1166},37,[269,1168,1169],{"class":275},"        }\n",[269,1171,1173],{"class":271,"line":1172},38,[269,1174,641],{"class":275},[218,1176],{},[221,1178,1180],{"id":1179},"triggering-the-call","Triggering the call",[211,1182,1183],{},"For now - we'll just trigger the call in the callback of the get token method. There are better ways to structure this - but for now this is simple to do and will cover the simple needs of the app.",[211,1185,1186],{},"Add a property on the view to hold the account. We cheat slightly here - using the dummy instance to set up \"default\" values for the view (currently just the name):",[260,1188,1190],{"className":446,"code":1189,"language":448,"meta":265,"style":265},"@State private var account = Account(accountId: \"\",\n                                         accountNumber: \"\",\n                                         ownerCustomerId: \"\",\n                                         name: \"Lommepenger\",\n                                         accountType: \"\",\n                                         available: 0.0,\n                                         balance: 0.0,\n                                         creditLimit: 0.0)\n",[248,1191,1192,1221,1232,1243,1255,1266,1278,1289],{"__ignoreMap":265},[269,1193,1194,1197,1200,1203,1205,1207,1209,1211,1214,1216,1219],{"class":271,"line":272},[269,1195,1196],{"class":455},"@State",[269,1198,1199],{"class":455}," private",[269,1201,1202],{"class":455}," var",[269,1204,1058],{"class":275},[269,1206,805],{"class":455},[269,1208,460],{"class":282},[269,1210,753],{"class":275},[269,1212,1213],{"class":282},"accountId",[269,1215,286],{"class":275},[269,1217,1218],{"class":339},"\"\"",[269,1220,293],{"class":275},[269,1222,1223,1226,1228,1230],{"class":271,"line":279},[269,1224,1225],{"class":282},"                                         accountNumber",[269,1227,286],{"class":275},[269,1229,1218],{"class":339},[269,1231,293],{"class":275},[269,1233,1234,1237,1239,1241],{"class":271,"line":296},[269,1235,1236],{"class":282},"                                         ownerCustomerId",[269,1238,286],{"class":275},[269,1240,1218],{"class":339},[269,1242,293],{"class":275},[269,1244,1245,1248,1250,1253],{"class":271,"line":311},[269,1246,1247],{"class":282},"                                         name",[269,1249,286],{"class":275},[269,1251,1252],{"class":339},"\"Lommepenger\"",[269,1254,293],{"class":275},[269,1256,1257,1260,1262,1264],{"class":271,"line":367},[269,1258,1259],{"class":282},"                                         accountType",[269,1261,286],{"class":275},[269,1263,1218],{"class":339},[269,1265,293],{"class":275},[269,1267,1268,1271,1273,1276],{"class":271,"line":379},[269,1269,1270],{"class":282},"                                         available",[269,1272,286],{"class":275},[269,1274,1275],{"class":282},"0.0",[269,1277,293],{"class":275},[269,1279,1280,1283,1285,1287],{"class":271,"line":391},[269,1281,1282],{"class":282},"                                         balance",[269,1284,286],{"class":275},[269,1286,1275],{"class":282},[269,1288,293],{"class":275},[269,1290,1291,1294,1296,1298],{"class":271,"line":404},[269,1292,1293],{"class":282},"                                         creditLimit",[269,1295,286],{"class":275},[269,1297,1275],{"class":282},[269,1299,1014],{"class":275},[211,1301,1302],{},"Update getToken in ContentView:",[260,1304,1306],{"className":446,"code":1305,"language":448,"meta":265,"style":265},"func getToken() {\n    if let config = self.config {\n        TokenService.getToken(config: config) { (accessToken) in\n            if let token = accessToken {\n                AccountService.getAccountDetails(config: config, token: token) { (account) in\n                    if let account = account {\n                        self.account = account\n                    } else {\n                        print(\"No account\")\n                    }\n                }\n            } else {\n                print(\"No token\")\n            }\n        }\n    }\n}\n",[248,1307,1308,1319,1337,1354,1368,1390,1404,1417,1427,1439,1444,1449,1458,1469,1473,1477,1481],{"__ignoreMap":265},[269,1309,1310,1313,1316],{"class":271,"line":272},[269,1311,1312],{"class":455},"func",[269,1314,1315],{"class":459}," getToken",[269,1317,1318],{"class":275},"() {\n",[269,1320,1321,1324,1326,1329,1331,1334],{"class":271,"line":279},[269,1322,1323],{"class":455},"    if",[269,1325,973],{"class":455},[269,1327,1328],{"class":275}," config ",[269,1330,805],{"class":455},[269,1332,1333],{"class":282}," self",[269,1335,1336],{"class":275},".config {\n",[269,1338,1339,1342,1345,1347,1349,1352],{"class":271,"line":296},[269,1340,1341],{"class":275},"        TokenService.",[269,1343,1344],{"class":282},"getToken",[269,1346,753],{"class":275},[269,1348,756],{"class":282},[269,1350,1351],{"class":275},": config) { (accessToken) ",[269,1353,965],{"class":455},[269,1355,1356,1358,1360,1363,1365],{"class":271,"line":311},[269,1357,970],{"class":455},[269,1359,973],{"class":455},[269,1361,1362],{"class":275}," token ",[269,1364,805],{"class":455},[269,1366,1367],{"class":275}," accessToken {\n",[269,1369,1370,1373,1376,1378,1380,1383,1385,1388],{"class":271,"line":367},[269,1371,1372],{"class":275},"                AccountService.",[269,1374,1375],{"class":282},"getAccountDetails",[269,1377,753],{"class":275},[269,1379,756],{"class":282},[269,1381,1382],{"class":275},": config, ",[269,1384,762],{"class":282},[269,1386,1387],{"class":275},": token) { (account) ",[269,1389,965],{"class":455},[269,1391,1392,1395,1397,1399,1401],{"class":271,"line":379},[269,1393,1394],{"class":455},"                    if",[269,1396,973],{"class":455},[269,1398,1058],{"class":275},[269,1400,805],{"class":455},[269,1402,1403],{"class":275}," account {\n",[269,1405,1406,1409,1412,1414],{"class":271,"line":391},[269,1407,1408],{"class":282},"                        self",[269,1410,1411],{"class":275},".account ",[269,1413,805],{"class":455},[269,1415,1416],{"class":275}," account\n",[269,1418,1419,1422,1425],{"class":271,"line":404},[269,1420,1421],{"class":275},"                    } ",[269,1423,1424],{"class":455},"else",[269,1426,987],{"class":275},[269,1428,1429,1432,1434,1437],{"class":271,"line":416},[269,1430,1431],{"class":282},"                        print",[269,1433,753],{"class":275},[269,1435,1436],{"class":339},"\"No account\"",[269,1438,1014],{"class":275},[269,1440,1441],{"class":271,"line":427},[269,1442,1443],{"class":275},"                    }\n",[269,1445,1446],{"class":271,"line":551},[269,1447,1448],{"class":275},"                }\n",[269,1450,1451,1454,1456],{"class":271,"line":573},[269,1452,1453],{"class":275},"            } ",[269,1455,1424],{"class":455},[269,1457,987],{"class":275},[269,1459,1460,1462,1464,1467],{"class":271,"line":582},[269,1461,992],{"class":282},[269,1463,753],{"class":275},[269,1465,1466],{"class":339},"\"No token\"",[269,1468,1014],{"class":275},[269,1470,1471],{"class":271,"line":590},[269,1472,1044],{"class":275},[269,1474,1475],{"class":271,"line":598},[269,1476,1169],{"class":275},[269,1478,1479],{"class":271,"line":606},[269,1480,641],{"class":275},[269,1482,1483],{"class":271,"line":614},[269,1484,314],{"class":275},[211,1486,1487],{},"So - when this is run - the view gets an account object.",[218,1489],{},[221,1491,1493],{"id":1492},"updating-the-view","Updating the view",[211,1495,1496],{},"We want to do two things:",[232,1498,1499,1502],{},[235,1500,1501],{},"Update ContentView to have a more suitable structure",[235,1503,1504],{},"Create an AccountView to hold all the account display info",[431,1506,1508],{"id":1507},"content-view","Content View",[211,1510,1511],{},"We want to have the outermost part to be a NavigationView with the scan button top right. Restructure as follows:",[260,1513,1515],{"className":446,"code":1514,"language":448,"meta":265,"style":265},"    var body: some View {\n        NavigationView {\n            VStack {\n                if (self.config != nil) {\n                    \u002F\u002F Do we have a config available?\n\n                    if (self.authenticated == false) {\n                        \u002F\u002F Waiting for Face\u002FTouch ID\n\n                        Text(\"Please authenticate\")\n                    } else {\n                        \u002F\u002F All good - show the account\n                        AccountView(account: account)\n                            \u002F\u002F and set the account name as the main page title\n                            .navigationBarTitle(Text(account.name), displayMode: .inline)\n                    }\n                } else {\n                    \u002F\u002F No config yet\n                    Text(\"You need to scan in a configuation\")\n                }\n            }\n            \u002F\u002F Scan button on nav bar top right\n            .navigationBarItems(trailing: Button(action: {\n                self.showingScanner = true\n            }) {\n                Image(systemName: \"qrcode\")\n                    .resizable()\n                    .frame(width: 32, height: 32)\n                }\n            )\n            \u002F\u002F Scan view sheet\n            .sheet(isPresented: $showingScanner) {\n                ScannerView(scannedData: Binding(\n                    get: { \"\" },\n                    set: self.newScanData\n                ))\n            }\n            \u002F\u002F Load config and auth on startup\n            .onAppear {\n                self.config = Config.loadConfig()\n\n                if (self.config != nil && self.authenticated == false) {\n                    self.askForAuth()\n                }\n            }\n        }\n    }\n",[248,1516,1517,1531,1538,1545,1566,1571,1575,1593,1598,1602,1614,1622,1627,1640,1645,1667,1671,1680,1685,1697,1701,1705,1710,1736,1749,1754,1771,1781,1809,1813,1818,1823,1838,1856,1869,1881,1886,1890,1895,1905,1922,1927,1955,1969,1974,1979,1984],{"__ignoreMap":265},[269,1518,1519,1522,1525,1528],{"class":271,"line":272},[269,1520,1521],{"class":455},"    var",[269,1523,1524],{"class":275}," body: ",[269,1526,1527],{"class":455},"some",[269,1529,1530],{"class":275}," View {\n",[269,1532,1533,1536],{"class":271,"line":279},[269,1534,1535],{"class":282},"        NavigationView",[269,1537,987],{"class":275},[269,1539,1540,1543],{"class":271,"line":296},[269,1541,1542],{"class":282},"            VStack",[269,1544,987],{"class":275},[269,1546,1547,1550,1553,1555,1558,1561,1564],{"class":271,"line":311},[269,1548,1549],{"class":455},"                if",[269,1551,1552],{"class":275}," (",[269,1554,954],{"class":282},[269,1556,1557],{"class":275},".config ",[269,1559,1560],{"class":455},"!=",[269,1562,1563],{"class":282}," nil",[269,1565,794],{"class":275},[269,1567,1568],{"class":271,"line":367},[269,1569,1570],{"class":820},"                    \u002F\u002F Do we have a config available?\n",[269,1572,1573],{"class":271,"line":379},[269,1574,548],{"emptyLinePlaceholder":547},[269,1576,1577,1579,1581,1583,1586,1588,1591],{"class":271,"line":391},[269,1578,1394],{"class":455},[269,1580,1552],{"class":275},[269,1582,954],{"class":282},[269,1584,1585],{"class":275},".authenticated ",[269,1587,1092],{"class":455},[269,1589,1590],{"class":282}," false",[269,1592,794],{"class":275},[269,1594,1595],{"class":271,"line":404},[269,1596,1597],{"class":820},"                        \u002F\u002F Waiting for Face\u002FTouch ID\n",[269,1599,1600],{"class":271,"line":416},[269,1601,548],{"emptyLinePlaceholder":547},[269,1603,1604,1607,1609,1612],{"class":271,"line":427},[269,1605,1606],{"class":282},"                        Text",[269,1608,753],{"class":275},[269,1610,1611],{"class":339},"\"Please authenticate\"",[269,1613,1014],{"class":275},[269,1615,1616,1618,1620],{"class":271,"line":551},[269,1617,1421],{"class":275},[269,1619,1424],{"class":455},[269,1621,987],{"class":275},[269,1623,1624],{"class":271,"line":573},[269,1625,1626],{"class":820},"                        \u002F\u002F All good - show the account\n",[269,1628,1629,1632,1634,1637],{"class":271,"line":582},[269,1630,1631],{"class":282},"                        AccountView",[269,1633,753],{"class":275},[269,1635,1636],{"class":282},"account",[269,1638,1639],{"class":275},": account)\n",[269,1641,1642],{"class":271,"line":590},[269,1643,1644],{"class":820},"                            \u002F\u002F and set the account name as the main page title\n",[269,1646,1647,1650,1653,1655,1658,1661,1664],{"class":271,"line":598},[269,1648,1649],{"class":275},"                            .",[269,1651,1652],{"class":282},"navigationBarTitle",[269,1654,753],{"class":275},[269,1656,1657],{"class":282},"Text",[269,1659,1660],{"class":275},"(account.name), ",[269,1662,1663],{"class":282},"displayMode",[269,1665,1666],{"class":275},": .inline)\n",[269,1668,1669],{"class":271,"line":606},[269,1670,1443],{"class":275},[269,1672,1673,1676,1678],{"class":271,"line":614},[269,1674,1675],{"class":275},"                } ",[269,1677,1424],{"class":455},[269,1679,987],{"class":275},[269,1681,1682],{"class":271,"line":622},[269,1683,1684],{"class":820},"                    \u002F\u002F No config yet\n",[269,1686,1687,1690,1692,1695],{"class":271,"line":630},[269,1688,1689],{"class":282},"                    Text",[269,1691,753],{"class":275},[269,1693,1694],{"class":339},"\"You need to scan in a configuation\"",[269,1696,1014],{"class":275},[269,1698,1699],{"class":271,"line":638},[269,1700,1448],{"class":275},[269,1702,1703],{"class":271,"line":644},[269,1704,1044],{"class":275},[269,1706,1707],{"class":271,"line":649},[269,1708,1709],{"class":820},"            \u002F\u002F Scan button on nav bar top right\n",[269,1711,1712,1715,1718,1720,1723,1725,1728,1730,1733],{"class":271,"line":654},[269,1713,1714],{"class":275},"            .",[269,1716,1717],{"class":282},"navigationBarItems",[269,1719,753],{"class":275},[269,1721,1722],{"class":282},"trailing",[269,1724,286],{"class":275},[269,1726,1727],{"class":282},"Button",[269,1729,753],{"class":275},[269,1731,1732],{"class":282},"action",[269,1734,1735],{"class":275},": {\n",[269,1737,1738,1741,1744,1746],{"class":271,"line":659},[269,1739,1740],{"class":282},"                self",[269,1742,1743],{"class":275},".showingScanner ",[269,1745,805],{"class":455},[269,1747,1748],{"class":282}," true\n",[269,1750,1751],{"class":271,"line":673},[269,1752,1753],{"class":275},"            }) {\n",[269,1755,1756,1759,1761,1764,1766,1769],{"class":271,"line":681},[269,1757,1758],{"class":282},"                Image",[269,1760,753],{"class":275},[269,1762,1763],{"class":282},"systemName",[269,1765,286],{"class":275},[269,1767,1768],{"class":339},"\"qrcode\"",[269,1770,1014],{"class":275},[269,1772,1773,1776,1779],{"class":271,"line":686},[269,1774,1775],{"class":275},"                    .",[269,1777,1778],{"class":282},"resizable",[269,1780,811],{"class":275},[269,1782,1783,1785,1788,1790,1793,1795,1798,1800,1803,1805,1807],{"class":271,"line":703},[269,1784,1775],{"class":275},[269,1786,1787],{"class":282},"frame",[269,1789,753],{"class":275},[269,1791,1792],{"class":282},"width",[269,1794,286],{"class":275},[269,1796,1797],{"class":282},"32",[269,1799,565],{"class":275},[269,1801,1802],{"class":282},"height",[269,1804,286],{"class":275},[269,1806,1797],{"class":282},[269,1808,1014],{"class":275},[269,1810,1811],{"class":271,"line":717},[269,1812,1448],{"class":275},[269,1814,1815],{"class":271,"line":722},[269,1816,1817],{"class":275},"            )\n",[269,1819,1820],{"class":271,"line":1126},[269,1821,1822],{"class":820},"            \u002F\u002F Scan view sheet\n",[269,1824,1825,1827,1830,1832,1835],{"class":271,"line":1137},[269,1826,1714],{"class":275},[269,1828,1829],{"class":282},"sheet",[269,1831,753],{"class":275},[269,1833,1834],{"class":282},"isPresented",[269,1836,1837],{"class":275},": $showingScanner) {\n",[269,1839,1840,1843,1845,1848,1850,1853],{"class":271,"line":1142},[269,1841,1842],{"class":282},"                ScannerView",[269,1844,753],{"class":275},[269,1846,1847],{"class":282},"scannedData",[269,1849,286],{"class":275},[269,1851,1852],{"class":282},"Binding",[269,1854,1855],{"class":275},"(\n",[269,1857,1858,1861,1864,1866],{"class":271,"line":1147},[269,1859,1860],{"class":282},"                    get",[269,1862,1863],{"class":275},": { ",[269,1865,1218],{"class":339},[269,1867,1868],{"class":275}," },\n",[269,1870,1871,1874,1876,1878],{"class":271,"line":1152},[269,1872,1873],{"class":282},"                    set",[269,1875,286],{"class":275},[269,1877,954],{"class":282},[269,1879,1880],{"class":275},".newScanData\n",[269,1882,1883],{"class":271,"line":1157},[269,1884,1885],{"class":275},"                ))\n",[269,1887,1888],{"class":271,"line":1166},[269,1889,1044],{"class":275},[269,1891,1892],{"class":271,"line":1172},[269,1893,1894],{"class":820},"            \u002F\u002F Load config and auth on startup\n",[269,1896,1898,1900,1903],{"class":271,"line":1897},39,[269,1899,1714],{"class":275},[269,1901,1902],{"class":282},"onAppear",[269,1904,987],{"class":275},[269,1906,1908,1910,1912,1914,1917,1920],{"class":271,"line":1907},40,[269,1909,1740],{"class":282},[269,1911,1557],{"class":275},[269,1913,805],{"class":455},[269,1915,1916],{"class":275}," Config.",[269,1918,1919],{"class":282},"loadConfig",[269,1921,811],{"class":275},[269,1923,1925],{"class":271,"line":1924},41,[269,1926,548],{"emptyLinePlaceholder":547},[269,1928,1930,1932,1934,1936,1938,1940,1942,1945,1947,1949,1951,1953],{"class":271,"line":1929},42,[269,1931,1549],{"class":455},[269,1933,1552],{"class":275},[269,1935,954],{"class":282},[269,1937,1557],{"class":275},[269,1939,1560],{"class":455},[269,1941,1563],{"class":282},[269,1943,1944],{"class":455}," &&",[269,1946,1333],{"class":282},[269,1948,1585],{"class":275},[269,1950,1092],{"class":455},[269,1952,1590],{"class":282},[269,1954,794],{"class":275},[269,1956,1958,1961,1964,1967],{"class":271,"line":1957},43,[269,1959,1960],{"class":282},"                    self",[269,1962,1963],{"class":275},".",[269,1965,1966],{"class":282},"askForAuth",[269,1968,811],{"class":275},[269,1970,1972],{"class":271,"line":1971},44,[269,1973,1448],{"class":275},[269,1975,1977],{"class":271,"line":1976},45,[269,1978,1044],{"class":275},[269,1980,1982],{"class":271,"line":1981},46,[269,1983,1169],{"class":275},[269,1985,1987],{"class":271,"line":1986},47,[269,1988,641],{"class":275},[431,1990,206],{"id":1991},"account-view",[211,1993,1994],{},"To start with - we will show the account number, and the balance\u002Favailable figures. Something like this:",[211,1996,1997],{},[1998,1999],"img",{"alt":206,"src":2000},"\u002Fimages\u002Fposts\u002F2020\u002F03\u002Faccount.png",[211,2002,2003],{},"Disponibelt - available. Saldo - balance.",[260,2005,2007],{"className":446,"code":2006,"language":448,"meta":265,"style":265},"struct AccountView: View {\n    public var account : Account\n\n    var body: some View {\n        VStack {\n            Text(account.accountNumber.accountFormat())\n                .padding(.bottom)\n                .padding(.top)\n                .font(.caption)\n            HStack {\n                VStack {\n                    Text(\"Disponibelt\")\n                        .font(.caption)\n                    Text(account.available.currency())\n                }\n                .frame(maxWidth: .infinity)\n                VStack {\n                    Text(\"Saldo\")\n                        .font(.caption)\n                    Text(account.balance.currency())\n                }\n                .frame(maxWidth: .infinity)\n            }\n            Spacer()\n        }\n    }\n}\n",[248,2008,2009,2023,2032,2036,2046,2053,2067,2078,2087,2097,2104,2111,2122,2131,2143,2147,2166,2172,2183,2191,2202,2206,2222,2226,2233,2237,2241],{"__ignoreMap":265},[269,2010,2011,2013,2016,2018,2021],{"class":271,"line":272},[269,2012,456],{"class":455},[269,2014,2015],{"class":459}," AccountView",[269,2017,286],{"class":275},[269,2019,2020],{"class":459},"View ",[269,2022,276],{"class":275},[269,2024,2025,2027,2029],{"class":271,"line":279},[269,2026,741],{"class":455},[269,2028,1202],{"class":455},[269,2030,2031],{"class":275}," account : Account\n",[269,2033,2034],{"class":271,"line":296},[269,2035,548],{"emptyLinePlaceholder":547},[269,2037,2038,2040,2042,2044],{"class":271,"line":311},[269,2039,1521],{"class":455},[269,2041,1524],{"class":275},[269,2043,1527],{"class":455},[269,2045,1530],{"class":275},[269,2047,2048,2051],{"class":271,"line":367},[269,2049,2050],{"class":282},"        VStack",[269,2052,987],{"class":275},[269,2054,2055,2058,2061,2064],{"class":271,"line":379},[269,2056,2057],{"class":282},"            Text",[269,2059,2060],{"class":275},"(account.accountNumber.",[269,2062,2063],{"class":282},"accountFormat",[269,2065,2066],{"class":275},"())\n",[269,2068,2069,2072,2075],{"class":271,"line":391},[269,2070,2071],{"class":275},"                .",[269,2073,2074],{"class":282},"padding",[269,2076,2077],{"class":275},"(.bottom)\n",[269,2079,2080,2082,2084],{"class":271,"line":404},[269,2081,2071],{"class":275},[269,2083,2074],{"class":282},[269,2085,2086],{"class":275},"(.top)\n",[269,2088,2089,2091,2094],{"class":271,"line":416},[269,2090,2071],{"class":275},[269,2092,2093],{"class":282},"font",[269,2095,2096],{"class":275},"(.caption)\n",[269,2098,2099,2102],{"class":271,"line":427},[269,2100,2101],{"class":282},"            HStack",[269,2103,987],{"class":275},[269,2105,2106,2109],{"class":271,"line":551},[269,2107,2108],{"class":282},"                VStack",[269,2110,987],{"class":275},[269,2112,2113,2115,2117,2120],{"class":271,"line":573},[269,2114,1689],{"class":282},[269,2116,753],{"class":275},[269,2118,2119],{"class":339},"\"Disponibelt\"",[269,2121,1014],{"class":275},[269,2123,2124,2127,2129],{"class":271,"line":582},[269,2125,2126],{"class":275},"                        .",[269,2128,2093],{"class":282},[269,2130,2096],{"class":275},[269,2132,2133,2135,2138,2141],{"class":271,"line":590},[269,2134,1689],{"class":282},[269,2136,2137],{"class":275},"(account.available.",[269,2139,2140],{"class":282},"currency",[269,2142,2066],{"class":275},[269,2144,2145],{"class":271,"line":598},[269,2146,1448],{"class":275},[269,2148,2149,2151,2153,2155,2158,2161,2164],{"class":271,"line":606},[269,2150,2071],{"class":275},[269,2152,1787],{"class":282},[269,2154,753],{"class":275},[269,2156,2157],{"class":282},"maxWidth",[269,2159,2160],{"class":275},": .",[269,2162,2163],{"class":282},"infinity",[269,2165,1014],{"class":275},[269,2167,2168,2170],{"class":271,"line":614},[269,2169,2108],{"class":282},[269,2171,987],{"class":275},[269,2173,2174,2176,2178,2181],{"class":271,"line":622},[269,2175,1689],{"class":282},[269,2177,753],{"class":275},[269,2179,2180],{"class":339},"\"Saldo\"",[269,2182,1014],{"class":275},[269,2184,2185,2187,2189],{"class":271,"line":630},[269,2186,2126],{"class":275},[269,2188,2093],{"class":282},[269,2190,2096],{"class":275},[269,2192,2193,2195,2198,2200],{"class":271,"line":638},[269,2194,1689],{"class":282},[269,2196,2197],{"class":275},"(account.balance.",[269,2199,2140],{"class":282},[269,2201,2066],{"class":275},[269,2203,2204],{"class":271,"line":644},[269,2205,1448],{"class":275},[269,2207,2208,2210,2212,2214,2216,2218,2220],{"class":271,"line":649},[269,2209,2071],{"class":275},[269,2211,1787],{"class":282},[269,2213,753],{"class":275},[269,2215,2157],{"class":282},[269,2217,2160],{"class":275},[269,2219,2163],{"class":282},[269,2221,1014],{"class":275},[269,2223,2224],{"class":271,"line":654},[269,2225,1044],{"class":275},[269,2227,2228,2231],{"class":271,"line":659},[269,2229,2230],{"class":282},"            Spacer",[269,2232,811],{"class":275},[269,2234,2235],{"class":271,"line":673},[269,2236,1169],{"class":275},[269,2238,2239],{"class":271,"line":681},[269,2240,641],{"class":275},[269,2242,2243],{"class":271,"line":686},[269,2244,314],{"class":275},[211,2246,2247],{},"Finally - we're using two extensions here.",[211,2249,2250],{},"Double currency() will return the value formatted for the current locale currency setting (in the simulator above - USD - on my son's iPhone it will be in NOK):",[260,2252,2254],{"className":446,"code":2253,"language":448,"meta":265,"style":265},"extension Double {\n    func currency() -> String {\n        let formatter = NumberFormatter()\n        formatter.numberStyle = .currency\n        guard let formatted = formatter.string(from: self as NSNumber) else {\n            return \"\\(self)\"\n        }\n\n        return formatted\n    }\n}\n",[248,2255,2256,2266,2284,2298,2308,2345,2363,2367,2371,2379,2383],{"__ignoreMap":265},[269,2257,2258,2261,2264],{"class":271,"line":272},[269,2259,2260],{"class":455},"extension",[269,2262,2263],{"class":282}," Double",[269,2265,987],{"class":275},[269,2267,2268,2271,2274,2277,2279,2282],{"class":271,"line":279},[269,2269,2270],{"class":455},"    func",[269,2272,2273],{"class":459}," currency",[269,2275,2276],{"class":275},"() ",[269,2278,788],{"class":455},[269,2280,2281],{"class":282}," String",[269,2283,987],{"class":275},[269,2285,2286,2288,2291,2293,2296],{"class":271,"line":296},[269,2287,799],{"class":455},[269,2289,2290],{"class":275}," formatter ",[269,2292,805],{"class":455},[269,2294,2295],{"class":282}," NumberFormatter",[269,2297,811],{"class":275},[269,2299,2300,2303,2305],{"class":271,"line":311},[269,2301,2302],{"class":275},"        formatter.numberStyle ",[269,2304,805],{"class":455},[269,2306,2307],{"class":275}," .currency\n",[269,2309,2310,2313,2315,2318,2320,2323,2326,2328,2331,2333,2335,2338,2341,2343],{"class":271,"line":367},[269,2311,2312],{"class":455},"        guard",[269,2314,973],{"class":455},[269,2316,2317],{"class":275}," formatted ",[269,2319,805],{"class":455},[269,2321,2322],{"class":275}," formatter.",[269,2324,2325],{"class":282},"string",[269,2327,753],{"class":275},[269,2329,2330],{"class":282},"from",[269,2332,286],{"class":275},[269,2334,954],{"class":282},[269,2336,2337],{"class":455}," as",[269,2339,2340],{"class":275}," NSNumber) ",[269,2342,1424],{"class":455},[269,2344,987],{"class":275},[269,2346,2347,2350,2353,2356,2358,2360],{"class":271,"line":379},[269,2348,2349],{"class":455},"            return",[269,2351,2352],{"class":339}," \"",[269,2354,2355],{"class":339},"\\(",[269,2357,954],{"class":282},[269,2359,1009],{"class":339},[269,2361,2362],{"class":339},"\"\n",[269,2364,2365],{"class":271,"line":391},[269,2366,1169],{"class":275},[269,2368,2369],{"class":271,"line":404},[269,2370,548],{"emptyLinePlaceholder":547},[269,2372,2373,2376],{"class":271,"line":416},[269,2374,2375],{"class":455},"        return",[269,2377,2378],{"class":275}," formatted\n",[269,2380,2381],{"class":271,"line":427},[269,2382,641],{"class":275},[269,2384,2385],{"class":271,"line":551},[269,2386,314],{"class":275},[211,2388,2389],{},"String accountFormat this adds spaces to get the usual display of 1234 56 78903. I find substring handling in swift to be a bit painful since you can't index into a string just with numbers - you have to use String.Index - so this extension takes care of that by defining an additional \"sub\" extension method returning a substring. I'm sure there are cleaner ways to do this but it does at least works:",[260,2391,2393],{"className":446,"code":2392,"language":448,"meta":265,"style":265},"extension String {\n    func sub(_ start: Int, _ count: Int) -> String{\n        return String(self[self.index(self.startIndex, offsetBy: start)..\u003Cself.index(self.startIndex, offsetBy: start + count)])\n    }\n\n    func accountFormat() -> String {\n        if (self.count == 11)   {\n            return String(\"\\(self.sub(0, 4)) \\(self.sub(4, 2)) \\(self.sub(6, 5))\")\n        } else {\n            return self\n        }\n    }\n}\n",[248,2394,2395,2403,2437,2504,2508,2512,2527,2550,2626,2635,2642,2646,2650],{"__ignoreMap":265},[269,2396,2397,2399,2401],{"class":271,"line":272},[269,2398,2260],{"class":455},[269,2400,2281],{"class":282},[269,2402,987],{"class":275},[269,2404,2405,2407,2410,2412,2415,2418,2420,2422,2424,2427,2429,2431,2433,2435],{"class":271,"line":279},[269,2406,2270],{"class":455},[269,2408,2409],{"class":459}," sub",[269,2411,753],{"class":275},[269,2413,2414],{"class":459},"_",[269,2416,2417],{"class":275}," start: ",[269,2419,290],{"class":282},[269,2421,565],{"class":275},[269,2423,2414],{"class":459},[269,2425,2426],{"class":275}," count: ",[269,2428,290],{"class":282},[269,2430,785],{"class":275},[269,2432,788],{"class":455},[269,2434,2281],{"class":282},[269,2436,276],{"class":275},[269,2438,2439,2441,2443,2445,2447,2450,2452,2454,2457,2459,2461,2463,2466,2468,2471,2474,2477,2479,2481,2483,2485,2487,2489,2491,2493,2495,2498,2501],{"class":271,"line":296},[269,2440,2375],{"class":455},[269,2442,2281],{"class":282},[269,2444,753],{"class":275},[269,2446,954],{"class":282},[269,2448,2449],{"class":275},"[",[269,2451,954],{"class":282},[269,2453,1963],{"class":275},[269,2455,2456],{"class":282},"index",[269,2458,753],{"class":275},[269,2460,954],{"class":282},[269,2462,1963],{"class":275},[269,2464,2465],{"class":282},"startIndex",[269,2467,565],{"class":275},[269,2469,2470],{"class":282},"offsetBy",[269,2472,2473],{"class":275},": start)",[269,2475,2476],{"class":455},"..\u003C",[269,2478,954],{"class":282},[269,2480,1963],{"class":275},[269,2482,2456],{"class":282},[269,2484,753],{"class":275},[269,2486,954],{"class":282},[269,2488,1963],{"class":275},[269,2490,2465],{"class":282},[269,2492,565],{"class":275},[269,2494,2470],{"class":282},[269,2496,2497],{"class":275},": start ",[269,2499,2500],{"class":455},"+",[269,2502,2503],{"class":275}," count)])\n",[269,2505,2506],{"class":271,"line":311},[269,2507,641],{"class":275},[269,2509,2510],{"class":271,"line":367},[269,2511,548],{"emptyLinePlaceholder":547},[269,2513,2514,2516,2519,2521,2523,2525],{"class":271,"line":379},[269,2515,2270],{"class":455},[269,2517,2518],{"class":459}," accountFormat",[269,2520,2276],{"class":275},[269,2522,788],{"class":455},[269,2524,2281],{"class":282},[269,2526,987],{"class":275},[269,2528,2529,2532,2534,2536,2538,2541,2544,2547],{"class":271,"line":391},[269,2530,2531],{"class":455},"        if",[269,2533,1552],{"class":275},[269,2535,954],{"class":282},[269,2537,1963],{"class":275},[269,2539,2540],{"class":282},"count",[269,2542,2543],{"class":455}," ==",[269,2545,2546],{"class":282}," 11",[269,2548,2549],{"class":275},")   {\n",[269,2551,2552,2554,2556,2558,2560,2562,2564,2566,2569,2571,2574,2576,2579,2582,2585,2587,2589,2591,2593,2595,2597,2600,2602,2604,2606,2608,2610,2612,2615,2617,2620,2622,2624],{"class":271,"line":404},[269,2553,2349],{"class":455},[269,2555,2281],{"class":282},[269,2557,753],{"class":275},[269,2559,850],{"class":339},[269,2561,2355],{"class":339},[269,2563,954],{"class":282},[269,2565,1963],{"class":339},[269,2567,2568],{"class":282},"sub",[269,2570,753],{"class":339},[269,2572,2573],{"class":282},"0",[269,2575,565],{"class":339},[269,2577,2578],{"class":282},"4",[269,2580,2581],{"class":339},"))",[269,2583,2584],{"class":339}," \\(",[269,2586,954],{"class":282},[269,2588,1963],{"class":339},[269,2590,2568],{"class":282},[269,2592,753],{"class":339},[269,2594,2578],{"class":282},[269,2596,565],{"class":339},[269,2598,2599],{"class":282},"2",[269,2601,2581],{"class":339},[269,2603,2584],{"class":339},[269,2605,954],{"class":282},[269,2607,1963],{"class":339},[269,2609,2568],{"class":282},[269,2611,753],{"class":339},[269,2613,2614],{"class":282},"6",[269,2616,565],{"class":339},[269,2618,2619],{"class":282},"5",[269,2621,2581],{"class":339},[269,2623,850],{"class":339},[269,2625,1014],{"class":275},[269,2627,2628,2631,2633],{"class":271,"line":416},[269,2629,2630],{"class":275},"        } ",[269,2632,1424],{"class":455},[269,2634,987],{"class":275},[269,2636,2637,2639],{"class":271,"line":427},[269,2638,2349],{"class":455},[269,2640,2641],{"class":282}," self\n",[269,2643,2644],{"class":271,"line":551},[269,2645,1169],{"class":275},[269,2647,2648],{"class":271,"line":573},[269,2649,641],{"class":275},[269,2651,2652],{"class":271,"line":582},[269,2653,314],{"class":275},[218,2655],{},[221,2657,2659],{"id":2658},"summary","Summary",[211,2661,2662],{},"At this point - we are able to start the app - scan a config if needed, authenticate with biometrics (face or touch ID) and now show the account name, number and balance\u002Favailable values.",[211,2664,2665],{},"The next step will be to show the last 10 transactions and then we will have the same functions that I had in the previous storyboard based app.",[218,2667],{},[211,2669,2670],{},[2671,2672,2679],"a",{"href":2673,"rel":2674,"target":2678},"https:\u002F\u002Fgithub.com\u002Fchrissearle\u002Flommepenger-swiftui",[2675,2676,2677],"nofollow","noopener","noreferer","_blank","GitHub Repository",[2681,2682,2683],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .s6RL2, html code.shiki .s6RL2{--shiki-default:#FDAEB7;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":265,"searchDepth":279,"depth":279,"links":2685},[2686,2690,2691,2695],{"id":223,"depth":279,"text":224,"children":2687},[2688,2689],{"id":433,"depth":296,"text":434},{"id":727,"depth":296,"text":728},{"id":1179,"depth":279,"text":1180},{"id":1492,"depth":279,"text":1493,"children":2692},[2693,2694],{"id":1507,"depth":296,"text":1508},{"id":1991,"depth":296,"text":206},{"id":2658,"depth":279,"text":2659},null,"2020-03-30 20:50 +0200","md","The app so far has the ability to get an authentication token. The next step is to actually use it.",{},"\u002F2020\u002F03\u002F30\u002Faccount-view",{"title":206,"description":213},"Revisiting the Sbanken API with SwiftUI",{"loc":2701},"2020\u002F03\u002F30\u002Faccount-view",[2707,448,2708,2709,2710],"ios","swiftui","xcode","sbanken","SsFTx5i9jFONGy1f48mBTdCn6NKQa3wvG1ndCVddTnw",1775293006856]