- 投稿日:2021-01-07T21:00:04+09:00
[Swift] スタティックプロパティ(static)を使ってみて分かったこと
はじめに
今回は、スタティックプロパティを理解するためにインスタンスプロパティも一緒に動かしてみたので、
比較しながら理解を深めていけたらなと思います。試してみたコードの説明
比較のためにインスタンスプロパティaとスタティックプロパティbを用意します。
関数getは、aとbの値の変更内容を表示するためのものです。struct Sample { var a = 0 static var b = 0 func get() -> String { return "aが\(a)、bが\(Sample.b)" } }インスタンスプロパティaを変更してみた
//3種類のインスタンスを作成します。 var S1 = Sample() var S2 = Sample() var S3 = Sample() //もちろん結果は同じです。 S1.get() //"aが0、bが0" S2.get() //"aが0、bが0" S3.get() //"aが0、bが0" //S2だけ変更を加えてみます。 S2.a = 3 //S2.aの部分のみが変更されています。 S1.get() //"aが0、bが0" S2.get() //"aが3、bが0" S3.get() //"aが0、bが0" //変数aにアクセスしようとすると、S1.aかS2.aかS3.aになる。 //インスタンス化したものに紐づいてアクセスするので、値の変更があった場合はそのインスタンスごとに変更になる。 //結果を見てもS2.aだけ変更されている事がわかる。スタティックプロパティbを変更してみた
Sample.b = 6 //全てのbが変更されている。 S1.get() //"aが0、bが6" S2.get() //"aが3、bが6" S3.get() //"aが0、bが6" //staticプロパティのbにアスセスするには、Sample.bになる。S1.bとアクセスする事はできない。 //インスタンスではなく、元の型自身に紐づいているプロパティである事がわかる。 //変更結果をみても、元になる型の内容を変更していることになるので、全ての値が変更されている事がわかる。
- 投稿日:2021-01-07T20:50:18+09:00
SFSymbolsを大きさと色を変えて表示する
はじめに
SFSymbolsを使うことでApple純正アプリでよく見かける画像を簡単にアプリに取り入れることができます。はじめ方についてはこちらで書いています。
let image = let image = UIImage(systemName: "mic")これだけでマイクアイコンを簡単に貼り付けられます。
大きさと色を変える
let image = UIImage(systemName: "mic", withConfiguration: UIImage.SymbolConfiguration(pointSize: 30, weight: .light, scale: .default))?.withTintColor(.black, renderingMode: .alwaysOriginal)
pointSize
で大きさを、withTintColor
で色を変更できます。ボタンを押した際の細かいエフェクトはrenderingModel
でいじれます。
- 投稿日:2021-01-07T19:27:13+09:00
【Swift】日本語を含むURLを使いたい時はaddingPercentEncodingせよ
知らなくて、APIのコールにつまずいた。
json -> swiftの型生成は quicktype を使った
(NewsAPIからデータを取得しようとしてデコードで失敗した話はこちら
【Swift】NewsAPIで取得したjsonのデコードで失敗して半日潰した話)APIで日本語を含むURLからデータをとってきたい時はaddingPercentEncodingを使う必要があった
なので日本語を含むURLの場合は以下のように書くべきだった
※keyword
に日本語が入るlet NewsApiURL="https://newsapi.org/v2/everything?q=\(keyword)&num=3&sortBy=latest&apiKey=\(myApiKey)" let encodedURL = NewsApiURL.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed) guard let url = NSURL(string: encodedURL!) else { print("無効なURLです。") return }のようにしてあげたらうまく行った。
- 投稿日:2021-01-07T19:24:15+09:00
【Swift】NewsAPIで取得したjsonのデコードで失敗して半日潰した話
前提
swiftの入門書を読んだだけの初学者がニュースアプリを作ってみたレベル。
ニュースはNewsAPIから取得。
取得したjsonは quicktype を使ってswiftのコードを生成した。
生成されたコード
// This file was generated from JSON Schema using quicktype, do not modify it directly. // To parse the JSON, add this file to your project and do: // // let welcome = try? newJSONDecoder().decode(Welcome.self, from: jsonData) import Foundation // MARK: - Welcome struct Welcome: Codable { let status: String let totalResults: Int let articles: [Article] } // MARK: - Article struct Article: Codable { let source: Source let author: String? let title, articleDescription: String let url: String let urlToImage: String let publishedAt: Date let content: String? enum CodingKeys: String, CodingKey { case source, author, title case articleDescription = "description" case url, urlToImage, publishedAt, content } } // MARK: - Source struct Source: Codable { let id: String? let name: String }デコード処理に失敗した理由はデータ型のミスだった
設定の問題だったのか特にエラーも吐かず、なんで失敗しているのかわからなかったので、jsonとquicktype生成したコードをひたすらにらめっこしていたら、publishedAtの型が犯人だとわかった
json
// MARK: - Article struct Article: Codable { 〜略〜 "publishedAt": "2020-12-07T14:30:00Z", 〜略〜 }生成コード
let publishedAt: Date修正後
let publishedAt: String上記の型を修正したら無事にデコードできた。
- 投稿日:2021-01-07T17:58:40+09:00
[Swift] Resultのもう一つの使い方?
最初に結論
Result
をcomputed propertyで使うのはどうですか?(※推奨ではなく提案)Computed propertyでも
throw
したい!Swiftでは次のようなコードは書けません(Swift 5現在)。
enum E: Error { case someError } struct S { var someProperty: throws Int { // ⛔️ コンパイルできない if Bool.random() { return 0 } else { throw E.someError } } }なぜならば、そもそもプロパティに対して
throws
というキーワードを使うことができないからです。throws
はfunc
(またはクロージャ)でしか使えないので、同様のことをしたい場合、普通はこうします:enum E: Error { case someError } struct S { func someProperty() throws -> Int { if Bool.random() { return 0 } else { throw E.someError } } }…ところで、
Result
を使うという手もありませんかね??enum E: Error { case someError } struct S { var someProperty: Result<Int, Error> { return .init(catching: { if Bool.random() { return 0 } else { throw E.someError } }) } }
Result
を使うメリット?特にメリットはありませんけども…あえて挙げるなら:
- “プロパティはあくまでプロパティであってほしい。
func
は使いたくない。”と思う気持ちを実現する。.get()
を呼び出すまで評価を遅延できる。おわりに
単なる思いつきですが、個人的には
public
じゃない(∴そのモジュール内で完結する)プロパティで使用すると便利な(場面がある)のではないかと考えています。
- 投稿日:2021-01-07T17:28:13+09:00
SwiftのDelegateの基本の基
SwiftのDelegateの基本の基
非エンジニアで最近Swiftを勉強している友人に「Delegateって何??」と質問された際を想定し、Delegateの基本についてまとめます。
※主に自身の毎日の復習・学習の機会創出、アウトプットによる知識の定着を目的としております。暖かい目で読んで頂けますと幸いです。
デリゲート(Delegate)
デリゲートは日本語訳は「委譲」です。
委譲は意味としては渡すや任せるです。swiftでのDelegateも委譲する機能になります!
一言で言うと「あるクラスが、他のクラスのインスタンスに、処理を任せることができる。」と言う説明を多くみます。
※(特定のインスタンスから別のインスタンスへ)
では、具体的に何が何に何を委譲するのか、具体例をみながら確認していきましょう!1.デリゲートは誰が任せるのか
誰が = 「クラスAが」
になります。つまり、あるクラスが自身の処理を任せます。
tableviewであれば「UITableViewクラス」が自身の処理を他人に任せます。
2.デリゲートは何に任せるのか
何に = 「クラスBに」
になります。override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self }swiftでtableViewを作成するときはこのような表記をすることがよくあるかと思います。
この例では「delegate」を「self」に任せています!
そして、ここでのselfはこのコードを記載している「ViewController」を意味します。
つまり、このコードを記載している「ViewController」に任せることになります!3.デリゲートは何を任せるのか
何を = 「自身(クラスA)の処理を」
になります。そして、この処理のことを具体的に「デリゲートメソッド」と言います。
ですので、正式には「自身のデリゲートメソッド内の処理」を他のクラス・インスタンスに任せる(委譲する)ことになります。tableviewであれば
swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
}
などがデリゲートメソッドに当たります。
※tableviewのデリゲートメソッドは他にもありますが、ここでは割愛まとめ
・Delegateは「あるクラスAが、クラスBのインスタンスに、処理(クラスAのデリゲートメソッド)を任せることができる。」機能
- 投稿日:2021-01-07T14:31:00+09:00
iOS14.2のIDFAまとめ
Xcode Version 12.3 (12C33) で検証
結果
OS isAdvertisingTrackingEnabled trackingAuthorizationStatus uuidString iOS13 true - 取得できた iOS13 false - 00000000-0000-0000-0000-000000000000 iOS14.2 true notDetermined 取得できた iOS14.2 false denied 00000000-0000-0000-0000-000000000000 iOS14.2 true authorized 取得できた iOS14.2 true denied 00000000-0000-0000-0000-000000000000 その他注意点
- isAdvertisingTrackingEnabled = false の場合 iOS14以降でもアラートが表示されずに denied 扱い
- requestTrackingAuthorization の completion は、アラートが表示されなくても呼ばれる
- アラートで選択肢を選ばずに無理やり電源を切った場合は denied 扱い
- restricted はよくわかりませんでしたが denied と同じ扱いで良さそう?
- isAdvertisingTrackingEnabled の値が iOS14 でもちゃんと取れるようになってるっぽい
- 今の所アラート出さないほうがIDFA取得できちゃいそう...
- ただ短い期間で動きが変わりがちなので安心できない...
- 投稿日:2021-01-07T14:31:00+09:00
iOS14.4のIDFAまとめ
iOS 14.4
Xcode Version 12.3 (12C33) で検証結果
OS isAdvertisingTrackingEnabled trackingAuthorizationStatus uuidString iOS13 true - 取得できた iOS13 false - 00000000-0000-0000-0000-000000000000 iOS14.4 true notDetermined 取得できた iOS14.4 false denied 00000000-0000-0000-0000-000000000000 iOS14.4 true authorized 取得できた iOS14.4 true denied 00000000-0000-0000-0000-000000000000 その他注意点
- isAdvertisingTrackingEnabled = false の場合 iOS14以降でもアラートが表示されずに denied 扱い
- requestTrackingAuthorization の completion は、アラートが表示されなくても呼ばれる
- アラートで選択肢を選ばずに無理やり電源を切った場合は denied 扱い
- restricted はよくわかりませんでしたが denied と同じ扱いで良さそう?
- isAdvertisingTrackingEnabled の値が iOS14 でもちゃんと取れるようになってるっぽい
- 今の所アラート出さないほうがIDFA取得できちゃいそう...
- ただ短い期間で動きが変わりがちなので安心できない...
備考
- iOS14.2とiOS14.4で調べましたが同じ挙動でした(2021/01/07)
- 投稿日:2021-01-07T08:11:24+09:00
[Swift5]コードでダークモード(暗い外観)の適用を回避する方法
- 投稿日:2021-01-07T01:58:29+09:00
iOS14でtrackingAuthorizationStatusのメモ
環境
- Xcode12.3
- iOS 14.2 iPhone SE
条件
トラッキング要求の動き
端末 トラッキング要求 アプリ status 許可 未 - notDetermined 済 許可 authorized 拒否 denied 拒否 未 - denied 済 許可 denied 拒否 denied 想定通り。
トラッキング要求を出していない状態で、端末設定を拒否から許可に戻すとちゃんとnotDeterminedに戻りますトラッキング要求を許可後の動き
アプリでトラッキング要求を許可した後に端末設定を拒否にした場合、こんなダイアログが出てくる
トラッキング要求をしていない場合や拒否した場合はダイアログがでない
「Appがトラッキングを続けることを許可する」を選ぶと、こんな画面なので端末で拒否しても取れるのかなと思ったらそんなことはなかった。
端末設定で再許可時のstatusをそのままにしてくれる動きのようです
ダイアログ status 端末設定で再許可時のstatus Appがトラッキングを続けることを許可する denied authorized 「Appにトラッキングの停止を要求」 denied denied
端末拒否時のトラッキング要求の動き
また、端末で拒否時にトラッキング要求をするとdeniedが設定されて端末設定を許可に戻してもdeniedのままになります。
トラッキング要求を出していなければnotDeterminedに戻ります端末拒否時
トラッキング要求 status 端末許可に変更後のstatus 未 denied notDetermined 済 denied denied