Skip to content

Commit

Permalink
Add device localization on ios (#532)
Browse files Browse the repository at this point in the history
This PR introduces a functionality for changing device localization on
ios.




https://github.com/user-attachments/assets/2259b6c2-c490-466c-bdcf-3fc3f7ad9381
  • Loading branch information
filip131311 authored Sep 19, 2024
1 parent 40cb534 commit e6292db
Show file tree
Hide file tree
Showing 15 changed files with 897 additions and 21 deletions.
184 changes: 184 additions & 0 deletions packages/vscode-extension/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/vscode-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-scroll-area": "^1.1.0",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-switch": "^1.0.3",
Expand Down
3 changes: 3 additions & 0 deletions packages/vscode-extension/src/common/Project.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { DeviceInfo } from "./DeviceManager";

export type Locale = string;

export type DeviceSettings = {
appearance: "light" | "dark";
contentSize: "xsmall" | "small" | "normal" | "large" | "xlarge" | "xxlarge" | "xxxlarge";
Expand All @@ -9,6 +11,7 @@ export type DeviceSettings = {
isDisabled: boolean;
};
hasEnrolledBiometrics: boolean;
locale: Locale;
};

export type ProjectState = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,10 @@ export class AndroidEmulatorDevice extends DeviceBase {
settings.location.latitude.toString(),
]);
}
return false;
}

async bootDevice() {
async bootDevice(settings: DeviceSettings) {
// this prevents booting device with the same AVD twice
await ensureOldEmulatorProcessExited(this.avdId);

Expand Down Expand Up @@ -162,6 +163,8 @@ export class AndroidEmulatorDevice extends DeviceBase {
});

this.serial = await initPromise;

await this.changeSettings(settings);
}

async openDevMenu() {
Expand Down
6 changes: 3 additions & 3 deletions packages/vscode-extension/src/devices/DeviceBase.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Disposable } from "vscode";
import { Preview } from "./preview";
import { BuildResult } from "../builders/BuildManager";
import { AppPermissionType, DeviceSettings, TouchPoint } from "../common/Project";
import { AppPermissionType, DeviceSettings, TouchPoint, Locale } from "../common/Project";
import { DeviceInfo, DevicePlatform } from "../common/DeviceManager";
import { tryAcquiringLock } from "../utilities/common";

Expand All @@ -14,8 +14,8 @@ export abstract class DeviceBase implements Disposable {

abstract get lockFilePath(): string;

abstract bootDevice(): Promise<void>;
abstract changeSettings(settings: DeviceSettings): Promise<void>;
abstract bootDevice(deviceSettings: DeviceSettings): Promise<void>;
abstract changeSettings(settings: DeviceSettings): Promise<boolean>;
abstract sendBiometricAuthorization(isMatch: boolean): Promise<void>;
abstract installApp(build: BuildResult, forceReinstall: boolean): Promise<void>;
abstract launchApp(build: BuildResult, metroPort: number, devtoolsPort: number): Promise<void>;
Expand Down
71 changes: 67 additions & 4 deletions packages/vscode-extension/src/devices/IosSimulatorDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { IOSDeviceInfo, IOSRuntimeInfo, DevicePlatform, DeviceInfo } from "../co
import { BuildResult } from "../builders/BuildManager";
import path from "path";
import fs from "fs";
import { AppPermissionType, DeviceSettings } from "../common/Project";
import { AppPermissionType, DeviceSettings, Locale } from "../common/Project";
import { EXPO_GO_BUNDLE_ID, fetchExpoLaunchDeeplink } from "../builders/expoGo";
import { ExecaError } from "execa";
import { IOSBuildResult } from "../builders/buildIOS";
Expand Down Expand Up @@ -76,8 +76,13 @@ export class IosSimulatorDevice extends DeviceBase {
]);
}

async bootDevice() {
async bootDevice(settings: DeviceSettings) {
const deviceSetLocation = getOrCreateDeviceSet(this.deviceUDID);

if (await this.shouldUpdateLocale(settings.locale)) {
await this.changeLocale(settings.locale);
}

try {
await exec("xcrun", ["simctl", "--set", deviceSetLocation, "boot", this.deviceUDID], {
allowNonZeroExit: true,
Expand All @@ -90,10 +95,39 @@ export class IosSimulatorDevice extends DeviceBase {
throw e;
}
}

await this.changeSettings(settings);
}

private async shouldUpdateLocale(locale: Locale): Promise<boolean> {
const deviceSetLocation = getOrCreateDeviceSet(this.deviceUDID);
const deviceLocale = await exec("/usr/libexec/PlistBuddy", [
"-c",
`print :AppleLocale`,
path.join(
deviceSetLocation,
this.deviceUDID,
"data",
"Library",
"Preferences",
".GlobalPreferences.plist"
),
]);
if (deviceLocale.stdout === locale) {
return false;
}
return true;
}

async changeSettings(settings: DeviceSettings) {
async changeSettings(settings: DeviceSettings): Promise<boolean> {
let shouldRestart = false;
const deviceSetLocation = getOrCreateDeviceSet(this.deviceUDID);

if (await this.shouldUpdateLocale(settings.locale)) {
shouldRestart = true;
this.changeLocale(settings.locale);
}

await exec("xcrun", [
"simctl",
"--set",
Expand Down Expand Up @@ -153,7 +187,10 @@ export class IosSimulatorDevice extends DeviceBase {
"-p",
"com.apple.BiometricKit.enrollmentChanged",
]);

return shouldRestart;
}

async sendBiometricAuthorization(isMatch: boolean) {
const deviceSetLocation = getOrCreateDeviceSet(this.deviceUDID);
await exec("xcrun", [
Expand All @@ -170,6 +207,26 @@ export class IosSimulatorDevice extends DeviceBase {
]);
}

private async changeLocale(newLocale: Locale): Promise<boolean> {
const deviceSetLocation = getOrCreateDeviceSet();
const languageCode = newLocale.match(/([^_-]*)/)![1];
await exec("/usr/libexec/PlistBuddy", [
"-c",
`set :AppleLanguages:0 ${languageCode}`,
"-c",
`set :AppleLocale ${newLocale}`,
path.join(
deviceSetLocation,
this.deviceUDID,
"data",
"Library",
"Preferences",
".GlobalPreferences.plist"
),
]);
return true;
}

async configureMetroPort(bundleID: string, metroPort: number) {
const deviceSetLocation = getOrCreateDeviceSet(this.deviceUDID);
const { stdout: appDataLocation } = await exec("xcrun", [
Expand Down Expand Up @@ -326,7 +383,13 @@ export class IosSimulatorDevice extends DeviceBase {
}

makePreview(): Preview {
return new Preview(["ios", "--id", this.deviceUDID, "--device-set", getOrCreateDeviceSet(this.deviceUDID)]);
return new Preview([
"ios",
"--id",
this.deviceUDID,
"--device-set",
getOrCreateDeviceSet(this.deviceUDID),
]);
}
}

Expand Down
Loading

0 comments on commit e6292db

Please sign in to comment.