第13回コベチケの会

コベリンの最近の取り組みとして、業務などで役立ちそうな知見を共有する会を開催することになりました。 そのついでに発表に使ったアジェンダもそのまま公開してしまおうという豪快な企画です。

※ アジェンダをそのままコピペして公開したものなので若干見にくい箇所もあるかもしれませんが、ご了承ください。

Swift の Property Observers の細かい動きの確認 @mironal

Swift のオンライン実行環境

コード書いたりレビューしてるときにちょっとだけ Swift の挙動が確認したくなったときには Xcode (や Xcode の Playground) を使うよりブラウザで Swift を動かせる実行環境のほうが便利。

以下のようなものがある。

Property Observers (willSet, didSet のやつのこと)の挙動

https://docs.swift.org/swift-book/LanguageGuide/Properties.html

継承した Class の property を override した場合

以下のようなコードの場合、Super Class, Sub Class それぞれの didSet はどうなる?

class Super {
  var value: Int = 0 {
    didSet { print("super:didSet") }
  }
}
class Sub: Super {
  override var value: Int {
    didSet { print("sub:didSet") }
  }
}
let sub = Sub()
sub.value = 1
// 何が出力される?

Compute Property には Property Observers つけれる?

class Super {
  var _aaaa: Double = 0
  var aaaa: Double {
    get { _aaaa }
    set(newValue) { _aaaa = newValue }
    didSet { print("aaaa") }
  }
}

継承した場合.

class Super {
  var _aaaa: Double = 0
  var aaaa: Double {
    get { _aaaa }
    set(newValue) { _aaaa = newValue }
  }
}

class Sub: Super {
  override var aaaa: Double {
    didSet {
      print("aaaa")
    }
  }
}

イニシャライザ内で変更すると willSet/didSet 呼ばれる?

class Super {
  var value: Int {
    didSet { print("didSet:value", value) }
  }

  init() {
    // didSet 呼ばれる?
    value = 1
  }
}

class Sub: Super {
  var valueSub: Int {
    didSet { print("didSet:valueSub", valueSub) }
  }

  override init() {

    // didSet 呼ばれる?
    valueSub = 0
    
    super.init()

    // didSet 呼ばれる?
    value = 10

    // didSet 呼ばれる?
    valueSub = 1

    // didSet 呼ばれる?
    add(3)
  }

  func add(_ v: Int) {
    value += v 
    valueSub += v
  }
}

let sub = Sub()

The willSet and didSet observers of superclass properties are called when a property is set in a subclass initializer, after the superclass initializer has been called. They aren’t called while a class is setting its own properties, before the superclass initializer has been called.

Array.append とかの操作で呼ばれる?

Array などに対するミュータブルな操作で willSet/didSet 呼ばれる?

class Super {
  var array: [Int] = [] {
    didSet { print("didSet:array", array) }
  }
}

let s = Super()

// didSet 呼ばれる?
s.array.append(1)

まとめ

  • override した Property に Property Observer を設定できる
    • Super クラスの Property Observer は消えない
  • Compute Property に Property Observer はつけれない
    • ただし継承した Sub Class ではつけれる
  • イニシャライザ内で変数を初期化した場合は Property Observer は呼ばれない
    • ただしイニシャライザ内でインスタンスメソッドを呼ぶと Property Observer は呼ばれる
  • Property にミュータブルな操作をすると Property Observer は呼ばれる

Screen Time のカテゴリーについて @takkumattsu

最初に

featherの開発をしていてユーザから、『Screen Timeに表示されるカテゴリーがfeatherはその他になっていて不便だ』という声が上がっていた

結論

  • TestFlightからインストールしたユーザはScreen Timeに表示されるカテゴリーがその他になる
  • 一度App Storeのアプリを上書きインストールすると治る

詳細は後述します。

Screen Time のカテゴリーについて

公式のドキュメントを調べたけどどこに設定した値が使われるか書かれているドキュメントは見つかりませんでした。

ただ色々調査して動かしてみて分かったのは以下でした。(調査内容は後述)

  • App Store Connect に設定されるプライマリーカテゴリーが表示される
  • image.png (22.5 kB)

調査したこと

Info.plistのApp Category(効果なし)

アプリの設定なのでinfo.plistとかにその項目があるのではと推測

ググってまず目に止まったのがこのスレッド→Screen Time category

developer.apple.com

解決方法は示されていなかったけどLSApplicationCategoryTypeってのがある記載されていた。ただMac専用でセットしても変わらなかったと書かれている。

developer.apple.com

↓実際変えてみたがScreen Timeのカテゴリーは変わらず

image.png (22.5 kB)

INFOPLIST_KEY_LSApplicationCategoryType (効果なし)

プロジェクトをcategoryで検索するとINFOPLIST_KEY_LSApplicationCategoryType という項目があった。これは前述したinfo.plistとは連動していなくxcodeprojに書き込まれる値みたいだった。
ちなみにINFOPLIST_KEY_LSApplicationCategoryTypeはググってもほとんど情報が出てこなかった。

image.png (54.1 kB)

ここをNoneからSosialNetworkingに変えたがScreen Timeのカテゴリーは変わらず

App Storeからインストールし直してみた(効果あり)

そうするとなんとカテゴリーがSNSに変わった!

心当たりとしては自分はfeatherはTestFlightやビルドしてインストールしていたので、もしかしてTestFlightやビルドして入れたアプリはScreen Timeのカテゴリーが設定されないのではというのに仮説

TestFlightからインストール AppStoreからインストール
image.png (55.3 kB) image.png (53.0 kB)

そしてここからがハマったポイントなんだけど、Screen Timeの値は一度カテゴリーがその他以外になると、(カテゴリーがその他になる)TestFlightをインストールしてもカテゴリーはその他には戻りませんでした。

項目
①AppStore→②TestFlight image.png (53.0 kB) image.png (53.0 kB)
①TestFlight→②AppStore image.png (55.3 kB) image.png (53.0 kB)

TestFlight→AppStoreの上書きの場合は正しく情報が変わっていますが、AppStore→TestFlightの方は年齢制限指定のみが変わっていました。

ハマったこと

Screen Timeの値はキャッシュがあるみたいでアプリの削除やiPhoneの再起動でもすぐには項目が消えませんでした。削除して結構な時間を放置したらScreen Timeから表示が消えました。

TestFlightにもカテゴリーを設定できないのか?

結論としては設定する項目はなさそうでした

meta1.png (141.9 kB) meta2.png (109.2 kB)

最後に

TestFlight版を利用していると起きる問題で実体を掴むまでに苦労しました。 あと自分はドキュメントを見つけることができなかったですけどこの辺の情報が纏まっているドキュメントがあったら教えて欲しいです…