iOS 26 compatibility (#4894)

This commit is contained in:
mark.dev
2026-01-22 16:39:52 +02:00
committed by GitHub
parent 6ae3f0fa29
commit 4203fe9ab7
34 changed files with 76 additions and 15 deletions
+1 -1
View File
@@ -1 +1 @@
16.1
26.1
+2 -6
View File
@@ -54,7 +54,7 @@ describe('Device', () => {
});
it('launchApp({newInstance: true}) + sendToHome() + launchApp() - should bring up previous instance', async () => {
await device.launchApp({newInstance: true});
await device.launchApp({newInstance: true });
await element(by.text('Sanity')).tap();
await element(by.text('Say Hello')).tap();
await device.sendToHome();
@@ -71,9 +71,6 @@ describe('Device', () => {
};
await device.launchApp({newInstance: true, languageAndLocale});
// iOS toast is hiding the element
await waitFor(element(by.text('Language'))).toBeVisible().withTimeout(1000);
await element(by.text('Language')).tap();
await expect(element(by.text(`Current locale: ${languageAndLocale.locale}`))).toBeVisible();
await expect(element(by.text(`Current language: ${languageAndLocale.language}`))).toBeVisible();
@@ -84,8 +81,7 @@ describe('Device', () => {
};
await device.launchApp({newInstance: true, languageAndLocale});
await waitFor(element(by.text('Language'))).toBeVisible().withTimeout(1000);
await element(by.text('Language')).tap();
await expect(element(by.text(`Current locale: ${languageAndLocale.locale}`))).toBeVisible();
await expect(element(by.text(`Current language: ${languageAndLocale.language}`))).toBeVisible();
+3 -1
View File
@@ -1,4 +1,5 @@
const { RESULTS } = require('react-native-permissions');
const { isIOS18OrHigher } = require('./utils/deviceInfo');
const BASIC_PERMISSIONS_TO_CHECK = [
'userTracking',
@@ -183,7 +184,8 @@ describe(':ios: Permissions', () => {
await device.launchApp({ permissions, delete: true });
await element(by.text('Permissions')).tap();
await expect(faceid).toHaveText(RESULTS.BLOCKED);
// iOS 18+ changed behavior: FaceID permissions set to NO now return DENIED instead of BLOCKED
await expect(faceid).toHaveText(isIOS18OrHigher() ? RESULTS.DENIED : RESULTS.BLOCKED);
});
});
});
+1 -1
View File
@@ -26,7 +26,7 @@ describe('Crash Handling', () => {
it('Should recover from app crash', async () => {
await device.launchApp({ newInstance: false });
await expect(element(by.text('Sanity'))).toBeVisible();
await waitFor(element(by.text('Sanity'))).toBeVisible();
});
/**
@@ -1,9 +1,9 @@
describe(":ios: Background-Foreground Transitions", () => {
it("Backgrounding and foregrounding an app should wait for transition to finish", async () => {
await device.launchApp({newInstance: true});
await device.launchApp({newInstance: true, launchArgs: { demoShowActiveNotification: true }});
await device.sendToHome();
await expect(element(by.text("Background"))).toExist();
await device.launchApp({newInstance: false});
await device.launchApp({newInstance: false, launchArgs: { demoShowActiveNotification: true }});
await expect(element(by.text("Active"))).toExist();
});
});
Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 90 KiB

+2 -2
View File
@@ -98,8 +98,8 @@ const config = {
type: 'ios.simulator',
headless: Boolean(process.env.CI),
device: {
type: 'iPhone 16 Pro Max',
os: '18.5'
type: 'iPhone 17 Pro',
os: '26.1'
},
},
+56
View File
@@ -0,0 +1,56 @@
/**
* Utility to get device OS version information
*/
let cachedIOSVersion = null;
/**
* Gets the iOS major version number
* @returns {Promise<number|null>} The iOS major version (e.g., 17, 18, 26) or null if not iOS
*/
async function getIOSMajorVersion() {
if (cachedIOSVersion !== null) {
return cachedIOSVersion;
}
try {
const { device: deviceHandle } = require('detox');
if (deviceHandle && deviceHandle.getPlatform && deviceHandle.getPlatform() !== 'ios') {
cachedIOSVersion = null;
return null;
}
if (deviceHandle && deviceHandle._device && deviceHandle._device.deviceConfig) {
const osVersion = deviceHandle._device.deviceConfig.device?.os;
if (osVersion) {
const majorVersion = parseInt(osVersion.split('.')[0], 10);
cachedIOSVersion = majorVersion;
return majorVersion;
}
}
} catch (e) {
console.warn('Could not determine iOS version, assuming iOS 18+');
}
cachedIOSVersion = 18;
return cachedIOSVersion;
}
/**
* Checks if iOS version is 18 or higher
* @returns {Promise<boolean>}
*/
async function isIOS18OrHigher() {
const majorVersion = await getIOSMajorVersion();
if (majorVersion === null) {
return false;
}
return majorVersion >= 18;
}
module.exports = {
getIOSMajorVersion,
isIOS18OrHigher,
};
+9 -2
View File
@@ -30,13 +30,18 @@
@end
#endif
@interface AppDelegate () <UNUserNotificationCenterDelegate>
@interface AppDelegate () <UNUserNotificationCenterDelegate> {
BOOL demoShowActiveNotification;
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
demoShowActiveNotification = [[NSUserDefaults standardUserDefaults] boolForKey:@"demoShowActiveNotification"];
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"demoShowActiveNotification"];
#if REACT_NATIVE_VERSION_MAJOR == 0 && REACT_NATIVE_VERSION_MINOR >= 79
self.reactNativeDelegate = [ReactNativeDelegate new];
self.reactNativeFactory = [[RCTReactNativeFactory alloc] initWithDelegate:self.reactNativeDelegate];
@@ -121,7 +126,9 @@
}
- (void)applicationDidBecomeActive:(NSNotification *)notification {
[self showOverlayMessageWithMessage:@"Active"];
if (demoShowActiveNotification) {
[self showOverlayMessageWithMessage:@"Active"];
}
}
- (void)applicationWillResignActive:(NSNotification *)notification {