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の時

textfieldの値をviewControllerに送る

オプショナル型とは変数にnilの代入を許容するデータ型で、反対に非オプショナル型はnilを代入できません。オプショナル型の変数にはデータ型の最後に「?」か「!」をつける。

textFieldの値をvarで宣言し、飛び先のview controllerでも変数を初期化する。segue.destionationで飛び先のviewcontrollerを取り、変数にsetする。

resultViewController.swift

@IBOutlet weak var sales: UITextField!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let CalcVC = segue.destination as! CalcViewController
        CalcVC.mySales = Int(self.sales.text!)!
    }

segueの値がshowResultの時のみ、変数に値を渡す。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard let identifier = segue.identifier else {
            return
        }
        if identifier == "showResult" {
            let CalcVC = segue.destination as! CalcViewController
            CalcVC.mySales = Int(self.sales.text!)!
        }
    }

iTunes connect feedback

appleからfeedbackが来た! なるほど、確かにジャンケンアプリとapp Iconの萌え系イラストの関係性は全くなかった(笑) 割とまともな審査のようです。

Your app’s metadata contains misleading content or content that is intended to deceive users.
Specifically, your app’s icon is irrelevant to your app’s content.
Once your app is fully compliant, resubmit your app for review.