Open4

iOSのメモ帳

たなたつたなたつ

AVURLAssetはファイルの拡張子が正しく設定されていないと tracks が空になることがあるので注意。

let asset = AVURLAsset(url: /* 拡張子のないパス */)
let audio = try await asset.loadTracks(withMediaType: .audio)) // []
let video = try await asset.loadTracks(withMediaType: .video)) // []
// await asset.loadValues(forKeys: ["tracks"]) // これを呼んでもダメ

任意のパスからファイルを読み取るならデータのヘッダーなどからファイルタイプを推定して拡張子を付与する処理が必要。
参考: https://github.com/sendyhalim/Swime

たなたつたなたつ

Swift 5.5からAssociated ValueのあるenumをCodableでencode/decodeする時に init などが自動生成されるようになった。
どんなJSONになるのかをメモ。

enum Animal: Codable {
  case 🐶(name: String)
  case 🐱(AnimalInfo)
  case 🐼(info: AnimalInfo)
}

struct AnimalInfo: Codable {
  let name: String
}

let animals: [Animal] = [
  .🐶(name: "Pochi"),
  .🐱(AnimalInfo(name: "Tama")),
  .🐼(info: AnimalInfo(name: "Xiang Xiang")),
]

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let jsonData = try! encoder.encode(animals)
print(String(decoding: jsonData, as: UTF8.self))

結果

[
  {
    "🐶" : {
      "name" : "Pochi"
    }
  },
  {
    "🐱" : {
      "_0" : {
        "name" : "Tama"
      }
    }
  },
  {
    "🐼" : {
      "info" : {
        "name" : "Xiang Xiang"
      }
    }
  }
]

Associated Valueに名前がない時に _0 が出てくるのが微妙なので名前をつけておくと良い。

たなたつたなたつ

SwiftUIのconfirmationDialogはiPadで表示した時につけたViewのサイズから吹き出しの位置を計算するので、注意
https://developer.apple.com/documentation/swiftui/view/confirmationdialog(_:ispresented:titlevisibility:actions:)-46zbb

横長のHStackconfirmationDialogを使ったパターン。

HStack {
    Button("Show") {
        isPresented = true
    }
    Spacer()
    Text("Hello")
}
.background(.thinMaterial)
.confirmationDialog("Dialog", isPresented: $isPresented) {
    Button("A") {}
    Button("B") {}
}

ButtonconfirmationDialogを使ったパターン。

HStack {
    Button("Show") {
        isPresented = true
    }
    .confirmationDialog("Dialog", isPresented: $isPresented) {
        Button("A") {}
        Button("B") {}
    }
    Spacer()
    Text("Hello")
}
.background(.thinMaterial)

タップした時にハイライトされる領域を意識して使ったほうが良い。

たなたつたなたつ

iCloudに置いてあって、まだ端末にキャッシュされてないファイルを読み込む時に、APIによってはファイルが読み込めないことがある。 (fileImporter 等)
その際は NSFileCoordinator で先にファイルをキャッシュしてからアクセスすると読み込めるようになる。

let coordinator = NSFileCoordinator()
var error: NSError? = nil
coordinator.coordinate(readingItemAt: url, options: [], error: &error) { url in
    // ここに来た時にはキャッシュされているのでアクセスできる
}