import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, XMLParserDelegate {
@IBOutlet weak var tableView: UITableView!
let feedUrl = URL(string: "https://news.yahoo.co.jp/pickup/rss.xml")!
var feedItems = [FeedItem]()
var currentElementName : String!
let ITEM_ELEMENT_NAME = "item"
let TITLE_ELEMENT_NAME = "title"
let LINK_ELEMENT_NAME = "link"
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.feedItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.subtitle, resultIdentifier: "Cell")
let feedItem = self.feedItems[indexPath.row]
cell.textLabel?.text = feedItem.title
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let feedItem = self.feedItems[indexPath.row]
UIApplication.shared.open(URL(string: feedItem.url)!, options: [:], completionHandler: nil)
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]){
self.currentElementName = nil
if elementName == ITEM_ELEMENT_NAME {
self.feedItems.append(FeedItem())
} else {
currentElementName = elementName
}
}
func parser(_ parser: XMLParser, foundCharacters string: String){
if self.feedItems.count > 0 {
let lastItem = self.feedItems[self.feedItems.count - 1]
switch self.currentElementName {
case TITLE_ELEMENT_NAME:
let tmpString = lastItem.title
lastItem.title = (tmpString != nil) ? tmpString! + string : string
case LINK_ELEMENT_NAME:
lastItem.url = string
default: break
}
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
self.currentElementName = nil
}
func parserDidEndDocument(_ parser: XMLParser){
self.tableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
let parser: XMLParser! = XMLParser(contentsOf: feedUrl)
parser.delegate = self
parser.parse()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
class FeedItem {
var title: String!
var url: String!
}
Category: Swift / SwiftUI
TableViewのdelegate
datasourceとdelegateをつなげる。

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