iOS関連のことを調べてみた2020年06月23日

iOS関連のことを調べてみた2020年06月23日
目次

ダークモード対応時にObjective-Cのコードがあったとき

# はじめに
歴史のあるiOSアプリのプロジェクトになると、Swift移行が完全でなくObjective-C(以降、objc)のコードが残存していたりするかと思います。

自分の関わるプロジェクトでは、ダークモード対応するぞ!ってなったときに、objcのコードが残っていたので一部objcで対応しました。

# コードから直接カラーセットを利用する
Storyboard上のパーツにカラー指定すれば基本的には対応できますが、中にはコード上でカスタムカラーを指定している場合もあります。

Swiftで記述する場合は`enum`でカラーセットを定義してそれを利用するとか、`UIColor`のextensionでカスタムカラーを定義する方法があるかと思います。

自分の関わったプロジェクトでは前者の方法で対応していたため、objcでenumを使えませんでした。
objc用で列挙型を定義するのもありかもしれませんが、いずれobjcを撲滅することを考えるとわざわざ定義するのに工数もかけたくありません。
直接呼び出せればいいやって感じです。

その時は以下のようにします。

“`objc
// ラ

元記事を表示

WWDC 2020 keynote:動画配信の視点で気になった点

AppleのWWDC 2020 (https://www.apple.com/apple-events/june-2020/ )の基調講演を見て、動画配信の目線で気になった点を簡単にまとめておきます。

# Picture in Picture機能がiOSにも追加

元々、既にiPadOSでは搭載されていた機能ですが、iOS 14からiPhoneでもPicture in Pictureが使えるようになります。
ネイティブのプレイヤーを利用していれば、問題なく使えると思いますが、サービスのコンセプトやコンテンツフォルダーとの許諾の関係上、そもそも許可したくない場合なども考えられますので、注意が必要です。

# iOS/iPadがApple SiliconのmacOSで動く

※SoCやらCPUの知識が乏しいため、不確かなことを書いていたらご指摘ください。

元々、昨年のmacOS Catalinaから、Mac CatalystでiPadアプリケーションをmacOSに提供することはできましたが、あくまでiPadアプリをmacOS向けに変換するものでした。

Apple Siliconは

元記事を表示

[Swift] iOS13以降で使用可能なAPIまとめ

#iOS APIとは?
Appleにより提供されている標準APIです。
意外と知られていない面白い機能などがたくさんあるので、今日はいくつかピックアップして紹介します。

#環境
– Xcode11.1
– Swift5

#Vision(Text Recognition)
![68022429-9b05bc00-fce7-11e9-8337-fa71db61583a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309711/fb884274-1d0e-4d63-0736-77a3066742f4.gif)

概要:
・文字の領域を識別
・文字認識

※英数字の識別しか現状できない

技術資料:
[How to use VNRecognizeTextRequest’s optical character recognition to detect text in an image](https://www.hackingwithswift.com/example-code/vision/how-to-

元記事を表示

Flutter duplicate symbols for architecture x86_64

## Flutter duplicate symbols for architecture x86_64の解決

### 34 duplicate symbols for architecture x86_64

“`
ld: 34 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
note: Using new build system
note: Building targets in parallel
note: Planning build
note: Constructing build description
“`

これが出たときの対処法。

### いつ起こったか
Flutterをiosで起動させようとした時に起こりました。

### 原因
FlutterのプロジェクトがiCloud内のディレクトリで作られている時に起こること

元記事を表示

Pix2PixをCoreMLモデルに変換

![pix2pix_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/c230ab22-83f4-d871-909a-a8a512423e7b.png)

*論文:[条件付き敵対的ネットワークによる画像から画像への変換](https://arxiv.org/abs/1611.07004)

CoreMLに変換することでpix2pix画像変換をiPhoneアプリで使用できます。

このストーリーでは、[TensorFlow CoreのPix2Pixチュートリアルモデル](https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/generative/pix2pix.ipynb)を使用します。

最初に、Colaboratoryでチュートリアルモデルをトレーニングします。

colabの以下のセルまでの全てのセルを実行します。

“`
fit(train_dataset、EPO

元記事を表示

MultiArrayからImageへの変換 CoreMLHelper

![pix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/a1cfa6ab-8fb3-5b09-70cf-825fe65c45fc.png)
CoreMLモデルの出力をMultiArrayからImageに変換するには、[CoreMLHelper](https://github.com/hollance/CoreMLHelpers)が便利です。

1、上のCoreMLHelper GitHubページリンクからCoreMLHelpersのファイルをダウンロードします。

2、XcodeプロジェクトにCoreMLHelpersファイルをコピーします。
スクリーンショット 2020-06-22 4.56.58.png
必要なフ

元記事を表示

UGATITをCoreMLモデルに変換。

UGATITはGANの応用で、深層画像生成技術の最先端です。
スクリーンショット 2020-05-19 11.09.03.png
たとえば、自撮りをアニメに変換できます。

[*論文](https://arxiv.org/abs/1907.10830)
[* GitHubプロジェクトページ](https://github.com/taki0112/UGATIT)

このUGATITのTensorFlowモデルをCoreMLモデルに変換して、iPhoneやiPadでこのモデルを使用できます。
以下の手順をmacのターミナルで実行します。

1、上のGitHubプロジェクトページからクローン。

“`
git clone https://github.com/taki0112/UGATIT.git
cd UGATI

元記事を表示

flutterで特定のプラグインをインストールした後にiOSのbuildができない

[stripe_payment](https://pub.dev/packages/stripe_payment#-readme-tab-)を初期状態から試そうと思ったがbuild出来なくて、ハマった。

### エラーメッセージ

“`
Automatically assigning platform `iOS` with version `8.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`
“`

podfileでiOSのバージョンが指定されていない。
その場合は8.0を勝手に指定するそうで、そのバージョンが対応していないからエラーになっているのかな?

#### Podfileを見る
ios/Podfileの先頭にあるコードにプロジェクトごとにOSのバージョンを定義して

元記事を表示

Moya を使ってレスポンス body が空の時、ステータスコードによって成功・失敗を判断する方法

以前初めて Moya を使った時に、

– API からステータスコードのみが送られる
– レスポンスの body は空である

というケースに出会いました。
僕は、「はいはい、どうせ空のレスポンスを作って上げれば `.success` 返ってくるんでしょ」を思って実装したのですが、、、
テストしてみると全然成功してくれない。。。

こんなときの対処法を紹介します。
**「こうすればもっとシンプルになるよ!」という意見あったら下さい!!!!!**

## 最初にざっくり結論
今から、実装クラスを紹介してから対処法を紹介しますが、すぐ知りたいせっかちな方のために結論を。

– パースを失敗させる
– すると、`MoyaError.objectMapping(Swift.Error, Response)` という `Error` になる
– この `Response` には `response` プロパティがある
– そして、 `response` プロパティには `statusCode: Int` があるからそれを見ればいい!!

## API の仕様

– 成功時: `status c

元記事を表示

【iOS】マナーモードでも音量固定で音を再生する

iOSアプリにおいて、
– デバイスがマナーモードの場合でも音を鳴らしたい
– その際、ユーザの音量設定に寄らず、固定の音量で鳴らしたい
場合があったので、実装方法を調べてみました。

##環境
– mac OS Catalina (10.15.4)
– Swift5
– Xcode11.4

##実装
下記リポジトリに実装サンプルを置いてあります。
https://github.com/r-kojima/FixedVolumeViewController

また、単純な音源の再生に関しては解説しません。
`AVAudioPlayer`などで検索をかけると実装サンプルがたくさん出てくると思います。

### マナーモード下で音を鳴らす
この実装は簡単です。
フィールドに宣言した`AVAudioSession`インスタンスの`setCategory(_:)`関数で
`.playAndRecord`を指定します。

“`
let audioSession = AVAudioSession.sharedInstance()
// マナーモードでも音を鳴らすようにする
try audioS

元記事を表示

Swift の文字列リテラルにおける特殊文字のエスケープ

Swift で以下のような特殊文字を文字列リテラルに含める時、皆さんどうしてますか??

– `”`: ダブルクォーテーション
– `’`: シングルクォーテーション
– `\`: バックスラッシュ
– tab: タブ文字
– return: 改行文字 (`\n`)
– : null 文字
– 先頭: キャリッジリターン

例えば、以下のような JSON 文字列を文字列リテラルに入れようとしても上手く行かないですよね。

“`json:exampleJson.json
{ “name”: “Daichi”, “age”: 23 }
“`

“`swift:swift
let jsonString: String = “{ “name”: “Daichi”, “age”: 23 }”
// コンパイルエラー (ダブルクォーテーションが文字列の終わりと認識されちゃう)
“`

この記事では、

– バックスラッシュでエスケープする方法
– Extended String Delimiters を使う方法

の 2 つの対処法を紹介します。

## `\` バックスラッシュでエスケ

元記事を表示

FlutterでFirebase Cloud MessagingとNotification Service Extension

先で書いた [FlutterでFirebase Cloud Messaging](https://qiita.com/yoshua/items/3c9d6674d30788b5d002) を基に、iOSのNotification Service Extensionを使った拡張を追加する。

これで以下を実現する。

– 通知センターに表示する通知に画像を表示する。

本ページより参照しているApple, Firebaseなどのページは以下。

– https://developer.apple.com/documentation/usernotifications/modifying_content_in_newly_delivered_notifications
– https://firebase.google.com/docs/cloud-messaging/ios/send-image

# 証明書などの用意

先で書いた [FlutterでFirebase Cloud Messaging](https://qiita.com/yoshua/items/3c9d6674d307

元記事を表示

iOS 13 以降ではウェブ上でセンサー値を扱う際にユーザからの許可が必要

## はじめに
iOS 12 までは、Safari の設定からセンサー値を利用していいか権限を与えていました。
iOS 13 からは仕様が変わり、サイトごとにユーザーからセンサー値の権限を JavaScript で与える必要があります。
**※ 永続化は不可能、セッション(?)ごとに許可を取る必要がある**
IMG_0758.PNG
ご覧の通り項目がなくなっていますね…(iOS 13.3.1 にて)

“`js
DeviceMotionEvent.requestPermission();
DeviceOrientationEvent.requestPermission();
“`

このコードを実行するとセンサー値の権限を制御できるウィンドウが出てくるのですが
どうやらタップやクリックなどの意図的なユーザの行動

元記事を表示

実機テストで「The maximum number of apps for free development profiles has been reached.」のエラーが出て困った話。

カメラアプリの開発中、実機にてビルドを行うと「Unable to install “product name”」と出てきて、詳細を確認すると「The maximum number of apps for free development profiles has been reached.」のエラーが出て、実機にアプリのインストールができず困った話です。

実行環境
xcode:version 11.5
iOSバージョン:13.5.1
実機:iphone7 

お金を払って開発者アカウントにしない限り、xcodeで作成したアプリを実機に三つまでしかインストールできないとのことだったのですが、私は初めての実機テストだったためインストールしているアプリが0の状態で、エラーが発生していました。

上記のような状況で、私が解決できた方法について以下に記載いたします。

1.Window->Devices and Simulators->実機を選択してOpen Consoleボタンをクリックしてログを表示
2.アプリを実行して実機へのインストールを試みる。
3.右上の検索にMIFreeProfi

元記事を表示

ランダム表示

#はじめに
・某プログラミング学習サイトの記録として、iOSでのランダム表示を行います
・Xcode Ver11.4 beta3
・前提:Storyboardを選択

#共通操作
・Simulatorの起動:Command + R
・配置した部品をコードに接続
 ・ViewController.swiftを表示
 ・部品を選択し、Controlを押しながらコードにD&D
 ・Connectionの設定
  ・outlet:コード内で変数として扱う場合
  ・Action:ボタンを押した時の処理をコード内に書きたい場合

#No1~No3:割愛

#No4:乱数の生成
・@IBAction func (関数名) (_sender:Any) {
  let random = arc4random_uniform(10); // 0~9までの変数を生成
  self.(ラベル名).text = String(random);
 }

#No5:乱数に対応するラベルを表示
@IBAction func (関数名) (_sender:Any) {
 // 表示する文字列を配列で用意
 let

元記事を表示

ウォークスルー後の通知許可とフォアグラウンド 通知を両立しようとしたら,うまくいかなかった件について

# TL;DR
– よくあるチュートリアルの後に通知許可の処理をしたらアプリ内通知が動かなかった
– これをするときは`appDelegate`にフォアグラウンド処理を書いてもダメ
– 通知許可の`viewController`にフォアグラウンド処理を書こう

# 何があったのか(前提条件)
– appDelegateの`application(_ application: UIApplication, didFinishLaunchingWithOptions)`に通知許可の処理を書かない -> アプリ立ち上げでは通知許可は出さない
– ウォークスルー終了後のメイン画面で通知許可を記述.
– フォアグラウンド通知のための`func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification:〜以下略)`はappDelegateに書いていた.

## 実行環境
|機材|バージョン|
|:–|:–|
|Xcode|11.5|
|iOS|13.5.1|
|Swift|5.2.4|

元記事を表示

SwiftでiOS開発している時に、Timerを利用したコードを、モダンでいい感じにUnitTestする方法

## 0. 初めに

画面タップイベントや、APIアクセスといった処理は、(ユーザーが連打するなどの場合を除けば)多くの場合一度きりの処理であることが多く、これらのロジックをUnitTestでテストするのは、そこまで大変ではないケースが多くを占めると思います。

しかしながら、一度きりではない処理を実装しないといけない(画面上にカウントダウンを表示させる場合など)ケースがあるのもまた事実かと思います。

いざTimerを使ったコードを書いてみると、実際に動かす場合はまぁよいにしろ、UnitTestを書くところで、

「どうやってテストしたらいいんだろう? :thinking: まさか待つわけにはいかないしな…」

といった感じで、思った以上にTimer部分のテストを書くのが難しく、Timer部分のUnitTestをスキップしてしまうことがあったり・・・するのではないでしょうか???

この記事では、そんなTimerのUnitTestが難しいなと思っている皆さんに向けて、僕はこんなふうにやったよという感じで、僕なりのテスト方法を提案しようと思います。

大まかに分けて下記のような流れ

元記事を表示

WKWebView オブジェクトの破棄後にデバッグ領域に “Could not find specified service” というメッセージが出力される

# 概要

`WKWebView` オブジェクトを破棄してから30秒ほど経過したら、以下の2つのエラーメッセージが Xcode のデバッグ領域に出力されます。

“`sh
Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service
“`

“`sh
Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service
“`

このメッセージが出力される原因について調査したところ、いろいろな情報を見つけたのですが、Apple Developer Forums のページで Apple Staff が返信しているものが最も信頼できる情報であると判断しました。そのページによると、このメッセージについては特に気にする必要はないとのことです。

# 確認環境

## ビルド環境
* macOS 10.15.5
* Xcode 11.5 (11E608c)

元記事を表示

UITableViewCellの選択アニメーション

設定画面などで複数の選択肢から一つを選択したときに、Cellにチェックマークをつけながらdeselectのアニメーションをする

※ `tableView.indexPathForSelectedRow` とかで選択中を判定すると、`tableView.deselectRow` をしたときに選択解除されてしまうのでCellの選択アニメーションがつけれない。なので変数で保持。

“`swift
class TableViewController: UITableViewController {

// 選択中のCellを保持しておく変数
var selectedRow = 0

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

// selectedRowならCheckmarkをつける
cell.accessoryType = s

元記事を表示

IBOutletのwillSetで他のIBOutletを参照してはいけない(Swift)

名前と名字のラベルからフルネームのラベルのテキストをセットする処理を考えます。
(わかりやすさのために `.text` を強制アンラップしています)

“`swift:×
import UIKit

final class FooViewController: UIViewController {
@IBOutlet private weak var firstNameLabel: UILabel!
@IBOutlet private weak var familyNameLabel: UILabel!
@IBOutlet private weak var fullNameLabel: UILabel! {
willSet {
newValue.text = “\(firstNameLabel.text!) \(fullNameLabel.text!)”
}
}
}
“`

このように記述した場合、以下のエラーが発生することがあります。

“`
Fatal error: Unexpectedl

元記事を表示

OTHERカテゴリの最新記事