アプリの初回起動時のみに表示される画面をテストする必要があったので、 XCUITest
でアプリを削除する方法について調べました。
WEB上にいくつか参考になる記事がありましたが、iOS 14のアプリ削除フローに対応した実装方法が見当たらなかったので内容をまとめてみました。
iOS 14でのアプリ削除フロー
iOS 14では以下のようにアプリを削除します
アプリアイコン長押し | コンテキストメニュー | 削除確認アラート1 | 削除確認アラート2 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
ホーム画面上で 削除するアプリのアイコンを長押し |
コンテキストメニューで アプリの削除を選択 |
ホーム画面からの削除確認アラートで アプリの削除を選択 |
アプリ削除確認アラートで アプリの削除を選択 |
ポイントは、アプリを削除(アンインストール)するための確認アラート(上記の 削除確認アラート2
)が表示される前に、アプリの情報を保持しつつホーム画面から削除するための確認アラート(上記の 削除確認アラート1
)が表示される点です。
なお、コンテキストメニューが表示されてもアプリアイコンの長押しをしたままにすると、各アプリアイコンの左上に削除を示すマイナスボタンが表示されますが、このフローだと上手く削除できない場合があることが分かったので、今回はコンテキストメニューでアプリの削除を選択するフローを採用しました。
実装
上記を踏まえて、アプリを削除するプログラムを書いていきましょう。
今回は SpringBoard 1 を使ってアプリの削除フローをSwiftで記述します。
struct Springboard {
private static let myAppName = "削除するアプリ名"
private static let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
static func deleteApp(name: String = myAppName) {
XCUIApplication().terminate()
springboard.activate()
XCUIDevice.shared.orientation = UIDeviceOrientation.portrait
Thread.sleep(forTimeInterval: 2.0)
let appIcon = springboard.icons[name]
guard appIcon.exists else {
return
}
appIcon.press(forDuration: 1.5)
let preferredLanguageCode = NSLocale.preferredLanguages[0].prefix(2)
// コンテキストメニュー
let firstDeleteButtonText = preferredLanguageCode == "ja" ? "Appを削除" : "Remove App"
springboard.buttons[firstDeleteButtonText].firstMatch.tap()
Thread.sleep(forTimeInterval: 1.0)
// 削除確認アラート1
let secondDeleteButtonText = preferredLanguageCode == "ja" ? "Appを削除" : "Delete App"
springboard.buttons[secondDeleteButtonText].firstMatch.tap()
Thread.sleep(forTimeInterval: 1.0)
// 削除確認アラート2
let thirdDeleteButtonText = preferredLanguageCode == "ja" ? "削除" : "Delete"
springboard.buttons[thirdDeleteButtonText].firstMatch.tap()
Thread.sleep(forTimeInterval: 0.5)
XCUIDevice.shared.press(.home)
}
}
確認アラートの文言などはシミュレーターの言語設定によって変わるので、必要に応じて切り分けます。
英語の Remove
と Delete
で表記ゆれしているのは地味にハマりどころかもしれません
これをUIテストのアプリ起動前に呼び出せば、毎回クリーンな状態でテストを実行できます
import XCTest
class MyAppUITests: XCTestCase {
override func setUp() {
super.setUp()
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// インスタンスメソッド `setUp()` で呼び出せば、各テストメソッドの実行前にアプリが削除される
Springboard.deleteApp()
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
XCUIApplication().launch()
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
...
}
別フロー
コンテキストメニューでアプリの削除を選択せずにアプリアイコンを長押ししつづけていると、アプリアイコンたちがプルプルしはじめ、各アプリアイコンの左上には削除を示すマイナスボタンが表示されます。
このフローでもアプリを削除できますが、環境やタイミングによっては想定外のアラートなどに邪魔されてしまうことがありました。
アプリアイコン長押し継続 | 確認アラート | 想定外のアラート |
---|---|---|
![]() |
![]() |
![]() |
コンテキストメニューが表示されても 無視して押し続ける |
削除確認アラートが表示されることもあるが | ホーム画面編集についてのお知らせアラートなどに 邪魔されてしまうこともある |
もちろんこれらを適切にハンドリングできればテストは可能だと思いますが、今回は採用を見送りました。
参考
-
iOSのホーム画面やそれに付随した機能を管理するためのソフトウェア ↩