ionic-team / ionic-team/capacitor

[Bug]: App does not load after transferring to a new iOS device if over the air updates are installed

Open
#8,336 5 comments 0 reactions 0 assignees View on GitHub
platform: ios
Dominant language
TypeScript
Stars
16.7k
Forks
1.3k
Avg merge
3d 15h
Merged PRs (30d)
10

Description

### Capacitor Version

💊 Capacitor Doctor 💊

Latest Dependencies:

@capacitor/cli: 8.0.2
@capacitor/core: 8.0.2
@capacitor/android: 8.0.2
@capacitor/ios: 8.0.2

Installed Dependencies:

@capacitor/cli: 7.4.2
@capacitor/core: 7.4.2
@capacitor/ios: 7.4.2
@capacitor/android: 7.4.2

### Other API Details

```Shell

```

### Platforms Affected

- [x] iOS
- [ ] Android
- [ ] Web

### Current Behavior

I reproduced this issue using 2 iPhones.

1. On the first iPhone, install your app with over the air update support.
2. Open the app and install an over the air update.
3. Factory reset the other iPhone. Set up this iPhone by transferring all apps and data from the first one.
4. Open your app. The app immediately closes.

I reproduced this issue with a debug build of the app to get more info. The steps are really similar.

1. On the first iPhone, install a development build of the app.
2. Install an over the air update.
3. Factory reset the other iPhone. During phone setup choose to transfer apps and data from the first phone. Your app isn't installed yet because it's a development build.
4. Enable developer mode on the second iPhone.
5. Install your development build of the app on this iPhone. It should use the settings and data transferred from the first phone. When the app opens, it'll immediately close.

I see the following in the Xcode debug console
```
⚡️ ERROR: Unable to load /var/mobile/Containers/Data/Application/6AE4ECD1-1214-4E0D-B66A-D668CD4C2EAC/Library/NoCloud/ionic_built_snapshots/release:824ca27
⚡️ This file is the root of your web app and must exist before
⚡️ Capacitor can run. Ensure you've run capacitor copy at least
⚡️ or, if embedding, that this directory exists as a resource directory.
```

### Expected Behavior

The app opens successfully.

### Project Reproduction

https://github.com/achien/capacitor-server-url-reproduction, relevant code is in [capacitor-welcome.js](https://github.com/achien/capacitor-server-url-reproduction/blob/main/app/src/js/capacitor-welcome.js)

### Additional Information

I debugged the issue and I have a patch that fixes the issue for me. The root cause is the app is trying to load from a directory that does not exist using the persisted `serverBasePath` in the key value store. The directory is `/NoCloud/ionic_built_snapshots/` which is not transferred from one phone to the other.

This issue does not happen on Android because it checks that the server path exists before using it, [here](https://github.com/ionic-team/capacitor/blob/8.0.2/android/capacitor/src/main/java/com/getcapacitor/Bridge.java#L300-L303). I was able to fix the issue on iOS by doing the same check.

```diff
diff --git a/ios/Capacitor/Capacitor/CAPBridgeViewController.swift b/ios/Capacitor/Capacitor/CAPBridgeViewController.swift
index a7285213..bd8fbaa4 100644
--- a/ios/Capacitor/Capacitor/CAPBridgeViewController.swift
+++ b/ios/Capacitor/Capacitor/CAPBridgeViewController.swift
@@ -93,10 +93,14 @@ import Cordova
if !isNewBinary && !descriptor.cordovaDeployDisabled {
if let persistedPath = KeyValueStore.standard["serverBasePath", as: String.self], !persistedPath.isEmpty {
if let libPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first {
- descriptor.appLocation = URL(fileURLWithPath: libPath, isDirectory: true)
+ let appLocation = URL(fileURLWithPath: libPath, isDirectory: true)
.appendingPathComponent("NoCloud")
.appendingPathComponent("ionic_built_snapshots")
.appendingPathComponent(URL(fileURLWithPath: persistedPath, isDirectory: true).lastPathComponent)
+
+ if FileManager.default.fileExists(atPath: appLocation.path) {
+ descriptor.appLocation = appLocation
+ }
}
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.