datasourceとdelegateをつなげる。
Category: Swift / SwiftUI
jsonデータの取得
import Foundation import CryptoSwift struct JsonSample : Codable { var high : Double var open : Double var bid : Double var currencyPairCode : String var ask : Double var low: Double } let listUrl = "https://www.gaitameonline.com/rateaj/getrate" let url = URL(string: listUrl) URLSession.shared.dataTask(with: url) { (data, response, error) in if error != nil { print(error!.localizedDescription) } guard let data = data else { return } let json = try? JSONDecoder().decode([JsonSample].self, from: data) }.resume() print(json.bid)
エラーになる。何故だ。。。
/tmp/EA9CF30B-2A75-422F-B05F-493561545E26.sMmRoI/main.swift:19:34: error: value of optional type ‘URL?’ not unwrapped; did you mean to use ‘!’ or ‘?’?
URLSession.shared.dataTask(with: url) { (data, response, error) in
^
!
/tmp/EA9CF30B-2A75-422F-B05F-493561545E26.sMmRoI/main.swift:29:7: error: use of unresolved identifier ‘json’
print(json.bid)
なんかうまくいかない。
let url:URL = URL(string: "")! let task = URLSession.shared.dataTask(with: url){ data, response, error in if let error = error{ print(error.localizedDescription) return } if let response = response as? HTTPURLResponse { print("response.statusCode = \(response.statusCode)") } } task.resume()
json
jasonを表示する
@IBAction func getJson(_ sender: Any) { let jsonString: String = "{\"id\":1, \"name\":\"Suzuki\"}" // JSON文字列をData型に変換 var personalData: Data = jsonString.data(using: String.Encoding.utf8)! do { // パースする let items = try JSONSerialization.jsonObject(with: personalData) as! Dictionary<String, Any> let cast = items["name"] as! String // メンバid Intにキャスト self.viewCenter.text = "\(cast)" } catch { print(error) } }
x-code:jsonデータを使ってドル円計算する
まず、foundatationをimportします。
import UIKit import Foundation
続いて、jsonを用意します。
let jsonString:String = "{\"dollaryen\":109, \"euroen\":110}" var code:Int = 0
prepareでjsonを取得して計算します。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let identifier = segue.identifier else { return } let personalData: Data = self.jsonString.data(using: String.Encoding.utf8)! do { let items = try JSONSerialization.jsonObject(with: personalData) as! Dictionary<String,Any> self.code = items["dollaryen"] as! Int } catch { self.code = 1 } if identifier == "showResult" { let CalcVC = segue.destination as! CalcViewController CalcVC.mySales = Int(Double(self.sales.text!)! / Double(self.code)) CalcVC.myProfit = Int(Double(self.profit.text!)! / Double(self.code)) CalcVC.myPrice = Int(self.price.text!)! CalcVC.myEPS = Double(self.eps.text!)! } }
あれ、エラーが出まくってる。。。
2018-06-03 18:42:56.527314+0900 account[17768:334563] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /Users/mac/Library/Developer/CoreSimulator/Devices/EA305F63-7A92-4933-9E03-89D80DFE7553/data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2018-06-03 18:42:56.539423+0900 account[17768:334563] [MC] Reading from private effective user settings.
2018-06-03 18:42:58.597654+0900 account[17768:334563] [Common] _BSMachError: port 8c03; (os/kern) invalid capability (0x14) “Unable to insert COPY_SEND”
2018-06-03 18:43:12.349999+0900 account[17768:338350] XPC connection interrupted
buildはsucceedするが、うまくいかないです。
swiftのjson読み込み
Foundationに含まれているJSONSerializationを使う
JSON文字列をパースするには、JSONSerialization.jsonObjectを使用する。
JSONSerializationJ .jsonObject(with JSONデータ: Data, options オプション)
import Foundation import CryptoSwift let jsonString: String = "{\"id\":3932, \"company\":\"Akatsuki\"}" var personalData: Data = jsonString.data(using: String.Encoding.utf8)! do { let items = try JSONSerialization.jsonObject(with: personalData) as! Dictionary<String,Any> print(items["id"] as! Int) print(items["company"] as! String) } catch { print(error) }
3932
Akatsuki
書き方を変える。
let jsonString: String = "{\"id\":3932, \"company\":\"Akatsuki\"}" var personalData: Data = jsonString.data(using: String.Encoding.utf8)! let items = try JSONSerialization.jsonObject(with: personalData) as! Dictionary<String,Any> var code:Int = items["id"] as! Int print(code)
3932
ではXcodeに当てはめましょう。
そもそも、import Foundationって、xcodeに使えるのか?
swift foundation
https://github.com/apple/swift-corelibs-foundation
The Foundation framework defines a base layer of functionality that is required for almost all applications. It provides primitive classes and introduces several paradigms that define functionality not provided by either the Objective-C runtime and language or Swift standard library and language.
よくわかりませんが、やってみましょう。
Info.plistとは
Info.plist
—————-
アプリで共通的な設定をInfo.plistという設定ファイルで行う。
Info.plistのファイル名は、「<プロジェクト名>Info.plist」という名前になっている。
http通信で、App Transport Security Settingsの下にAllow Arbitrary Loadsを追加する。
swift: intを浮動小数点数で割る時
CalcVC.mySales = Int(self.sales.text!)! / 109 CalcVC.myProfit = Int(self.profit.text!)! / 109.53 CalcVC.myPrice = Int(self.price.text!)! CalcVC.myEPS = Double(self.eps.text!)!
Int(self.profit.text!)! / 109.53 とすると、エラーになるが、Int(self.profit.text!)! / 109に変えるとエラーが消える。為替の世界だと、109.00と109.53は全く違うので、Int(self.profit.text!)の方の型を変えないといけない。
あれ、さらにエラーが出た
Replace 'Double(self.sales.text!)! / 109.53' with 'Int(Double(self.sales.text!)! / 109.53)'
なるほど。受け取り側の型に合わせるのね。賢すぎ。
intでcastします。
if identifier == "showResult" { let CalcVC = segue.destination as! CalcViewController CalcVC.mySales = Int(Double(self.sales.text!)! / 109.53) CalcVC.myProfit = Int(Double(self.profit.text!)! / 109.53) CalcVC.myPrice = Int(self.price.text!)! CalcVC.myEPS = Double(self.eps.text!)! }
なるほど
109.53で割った数がintで表示されます。
ドル円の値をjsonで取得したい。(いよいよ趣旨に少しづつ近づいて来ました。)
swiftのDouble(浮動小数型)
swiftでDouble(浮動小数型)を使う。sales, profit, stockpriceはint, epsはdoubleで定義する。
var mySales:Int = 0 var myProfit:Int = 0 var myPrice:Int = 0 var myEPS:Double = 0.0
outletでconnectする。
@IBOutlet weak var salesLabel: UILabel! @IBOutlet weak var profitLabel: UILabel! @IBOutlet weak var priceLabel: UILabel! @IBOutlet weak var epsLabel: UILabel!
ResultViewController.swift
遷移先のViewControllerに値をセットする。
if identifier == "showResult" { let CalcVC = segue.destination as! CalcViewController CalcVC.mySales = Int(self.sales.text!)! CalcVC.myProfit = Int(self.profit.text!)! CalcVC.myPrice = Int(self.price.text!)! CalcVC.myEPS = Double(self.eps.text!)! }
CalcViewController.swift
データを受け取り、textで表示する。
override func viewDidLoad() { super.viewDidLoad() self.salesLabel.text = "\(self.mySales)" self.profitLabel.text = "\(self.myProfit)" self.priceLabel.text = "\(self.myPrice)" self.epsLabel.text = "\(self.myEPS)" // Do any additional setup after loading the view. }
さあ、compileしてみましょう。
textfieldに入力した値がcalcViewController.swiftに渡っています。
売り上げ(sales)と経常利益(profit)はドルで表示したい。
円からドル円(109.529025)で割ってみましょう。
shouldPerformSeguedでalertをだす
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { if identifier == "showResult" { guard self.sales.text != "" else{ let alertController = UIAlertController(title: "Error", message: "Please enter your name", preferredStyle: .alert) let defaultAction = UIAlertAction(title:"OK", style: .default, handler: nil) alertController.addAction(defaultAction) self.present(alertController, animated: true, completion: nil) return false } return true } return true }
初期
text fieldがnilの時
textformの値を受け取って表示する
var mySales:Int = 0 @IBOutlet weak var salesLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() self.salesLabel.text = "\(self.mySales)" // Do any additional setup after loading the view. }