Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

[eject] Added support for device families #2505

Merged
merged 1 commit into from
Aug 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 29 additions & 30 deletions packages/config/src/ios/DeviceFamily.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import * as fs from 'fs-extra';

import { ExpoConfig } from '../Config.types';
import { addWarningIOS } from '../WarningAggregator';
import { getPbxproj } from './utils/Xcodeproj';

export function getSupportsTablet(config: ExpoConfig) {
export function getSupportsTablet(config: ExpoConfig): boolean {
if (config.ios?.supportsTablet) {
return config.ios?.supportsTablet;
return !!config.ios?.supportsTablet;
}

return false;
}

export function getIsTabletOnly(config: ExpoConfig) {
export function getIsTabletOnly(config: ExpoConfig): boolean {
if (config.ios?.isTabletOnly) {
return config.ios.isTabletOnly;
return !!config.ios.isTabletOnly;
}

return false;
}

export function getDeviceFamilies(config: ExpoConfig) {
export function getDeviceFamilies(config: ExpoConfig): number[] {
const supportsTablet = getSupportsTablet(config);
const isTabletOnly = getIsTabletOnly(config);

Expand All @@ -31,35 +33,32 @@ export function getDeviceFamilies(config: ExpoConfig) {
}
}

/**
* Wrapping the families in double quotes is the only way to set a value with a comma in it.
* Use a number when only value is returned, this better emulates Xcode.
*
* @param deviceFamilies
*/
export function formatDeviceFamilies(deviceFamilies: number[]): string | number {
return deviceFamilies.length === 1 ? deviceFamilies[0] : `"${deviceFamilies.join(',')}"`;
}

/**
* Add to pbxproj under TARGETED_DEVICE_FAMILY
*/
export function setDeviceFamily(config: ExpoConfig, projectRoot: string) {
const supportsTablet = getSupportsTablet(config);
const isTabletOnly = getIsTabletOnly(config);
const deviceFamilies = formatDeviceFamilies(getDeviceFamilies(config));

if (isTabletOnly) {
addWarningIOS(
'isTabletOnly',
'You will need to configure this in the "General" tab for your project target in Xcode.'
);
} else if (supportsTablet) {
addWarningIOS(
'supportsTablet',
'You will need to configure this in the "General" tab for your project target in Xcode.'
);
const project = getPbxproj(projectRoot);
const configurations = project.pbxXCBuildConfigurationSection();
// @ts-ignore
for (const { buildSettings } of Object.values(configurations || {})) {
// Guessing that this is the best way to emulate Xcode.
// Using `project.addToBuildSettings` modifies too many targets.
if (typeof buildSettings?.PRODUCT_NAME !== 'undefined') {
buildSettings.TARGETED_DEVICE_FAMILY = deviceFamilies;
}
}

// TODO: we might need to actually fork the "xcode" package to make this work
// See: https://github.com/apache/cordova-node-xcode/issues/86
//
// const project = getPbxproj(projectRoot);
// Object.entries(project.pbxXCBuildConfigurationSection())
// .filter(removeComments)
// .filter(isBuildConfig)
// .filter(removeTestHosts)
// .forEach(({ 1: { buildSettings } }: any) => {
// buildSettings.TARGETED_DEVICE_FAMILY = '1';
// });
// fs.writeFileSync(project.filepath, project.writeSync());
fs.writeFileSync(project.filepath, project.writeSync());
}
14 changes: 13 additions & 1 deletion packages/config/src/ios/__tests__/DeviceFamily-test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { getDeviceFamilies, getIsTabletOnly, getSupportsTablet } from '../DeviceFamily';
import {
formatDeviceFamilies,
getDeviceFamilies,
getIsTabletOnly,
getSupportsTablet,
} from '../DeviceFamily';

const TABLET_AND_PHONE_SUPPORTED = [1, 2];
const ONLY_PHONE_SUPPORTED = [1];
Expand Down Expand Up @@ -38,6 +43,13 @@ describe('device family', () => {
expect(getDeviceFamilies({ ios: { isTabletOnly: true } })).toEqual(ONLY_TABLET_SUPPORTED);
});

// It's important that this format is always correct.
// Otherwise the xcode parser will throw `Expected ".", "/*", ";", or [0-9] but "," found.` when we attempt to write to it.
it(`formats the families correctly`, () => {
expect(formatDeviceFamilies([1])).toEqual(1);
expect(formatDeviceFamilies([1, 2, 3])).toEqual(`"1,2,3"`);
});

// TODO: update tests to run against pbxproj
// it(`sets to phone only if no value is provided`, () => {
// expect(setDeviceFamily({}, {})).toMatchObject({ UIDeviceFamily: ONLY_PHONE_SUPPORTED });
Expand Down