Skip to content
This repository was archived by the owner on Feb 10, 2026. It is now read-only.

Commit 6e5f23a

Browse files
Fce 1717 configure plugins (#445)
## Description Describe your changes in detail ## Motivation and Context Why is this change required? What problem does it solve? If it fixes an open issue, please link to the issue here. ## How has this been tested? Please describe in detail how you tested your changes. Include details of your testing environment, devices (ex. Iphone XYZ ios X.X.X & Samsung XYZ android X.X.X) ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) ## Checklist: - [ ] My code follows the code style of this project. - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. ## Screenshots (if appropriate)
1 parent a2b1bc9 commit 6e5f23a

4 files changed

Lines changed: 88 additions & 56 deletions

File tree

common/plugins/src/with-custom-config-ios.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ const removeGeneratedBlockIos = (podfileContent: string, marker: string) => {
66
return podfileContent.replace(regex, '');
77
};
88

9-
const replaceCloudClientForExtension = (podfileContent: string) => {
10-
const targetName = 'FishjamScreenBroadcastExtension';
9+
const replaceCloudClientForExtension = (
10+
podfileContent: string,
11+
extensionTargetName?: string,
12+
) => {
13+
const extTargetName = extensionTargetName || 'FishjamScreenBroadcastExtension';
1114
const podToReplace = "pod 'FishjamCloudClient/Broadcast'";
1215
const replacementPod = `
1316
${INFO_GENERATED_COMMENT_IOS}
1417
pod 'FishjamCloudClient/Broadcast', :path => '../../../'`;
1518

1619
const targetRegex = new RegExp(
17-
`target '${targetName}' do[\\s\\S]*?${podToReplace}[\\s\\S]*?end`,
20+
`target '${extTargetName}' do[\\s\\S]*?${podToReplace}[\\s\\S]*?end`,
1821
'g',
1922
);
2023

@@ -36,16 +39,16 @@ const replaceCloudClientForMainApp = (
3639
return podfileContent;
3740
};
3841

39-
export const withCustomConfigIos: ConfigPlugin<{ targetName: string }> = (
42+
export const withCustomConfigIos: ConfigPlugin<{ targetName: string; extensionTargetName?: string }> = (
4043
config,
41-
{ targetName },
44+
{ targetName, extensionTargetName },
4245
) => {
4346
config = withPodfile(config, (configuration) => {
4447
let podfile = configuration.modResults.contents;
4548

4649
podfile = removeGeneratedBlockIos(podfile, INFO_GENERATED_COMMENT_IOS.trim());
4750

48-
podfile = replaceCloudClientForExtension(podfile);
51+
podfile = replaceCloudClientForExtension(podfile, extensionTargetName);
4952
podfile = replaceCloudClientForMainApp(targetName, podfile);
5053

5154
configuration.modResults.contents = podfile;

common/plugins/src/with-local-paths-for-native-packages.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import { withCustomConfigAndroid } from "./with-custom-config-android";
44

55
type PluginProps = {
66
iosTargetName?: string;
7+
extensionTargetName?: string;
78
};
89

910
const withLocalPathsForNativePackages: ConfigPlugin<PluginProps> = (
1011
config,
1112
props = {},
1213
) => {
13-
const { iosTargetName } = props;
14+
const { iosTargetName, extensionTargetName } = props;
1415

15-
config = withCustomConfigIos(config, { targetName: iosTargetName });
16+
config = withCustomConfigIos(config, { targetName: iosTargetName, extensionTargetName });
1617
config = withCustomConfigAndroid(config);
1718

1819
return config;

packages/react-native-client/plugin/src/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ export type FishjamPluginOptions =
88
iphoneDeploymentTarget?: string;
99
enableScreensharing?: boolean;
1010
supportsPictureInPicture?: boolean;
11+
appGroupContainerId?: string;
12+
mainTargetName?: string;
13+
broadcastExtensionTargetName?: string;
1114
};
1215
}
1316
| undefined;

packages/react-native-client/plugin/src/withFishjamIos.ts

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,18 @@ import * as fs from 'promise-fs';
1010
import * as path from 'path';
1111
import { FishjamPluginOptions } from './types';
1212

13-
const SBE_TARGET_NAME = 'FishjamScreenBroadcastExtension';
14-
export const SBE_PODFILE_SNIPPET = `
15-
target '${SBE_TARGET_NAME}' do
16-
pod 'FishjamCloudClient/Broadcast'
17-
end`;
13+
function getSbeTargetName(props: FishjamPluginOptions) {
14+
return (
15+
props?.ios?.broadcastExtensionTargetName ||
16+
'FishjamScreenBroadcastExtension'
17+
);
18+
}
19+
20+
export function getSbePodfileSnippet(props: FishjamPluginOptions) {
21+
const targetName = getSbeTargetName(props);
22+
return `\ntarget '${targetName}' do\n pod 'FishjamCloudClient/Broadcast'\nend`;
23+
}
24+
1825
const TARGETED_DEVICE_FAMILY = `"1,2"`;
1926
const IPHONEOS_DEPLOYMENT_TARGET = '15.1';
2027
const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
@@ -28,8 +35,10 @@ async function updateFileWithRegex(
2835
fileName: string,
2936
regex: RegExp,
3037
value: string,
38+
props: FishjamPluginOptions,
3139
) {
32-
const filePath = `${iosPath}/${SBE_TARGET_NAME}/${fileName}`;
40+
const targetName = getSbeTargetName(props);
41+
const filePath = `${iosPath}/${targetName}/${fileName}`;
3342
let file = await fs.readFile(filePath, { encoding: 'utf-8' });
3443
file = file.replace(regex, value);
3544
await fs.writeFile(filePath, file);
@@ -39,25 +48,26 @@ async function updateFileWithRegex(
3948
* Inserts a required target to Podfile.
4049
* This is needed to provide the dependency of FishjamCloudClient/Broadcast to the extension.
4150
*/
42-
async function updatePodfile(iosPath: string) {
51+
async function updatePodfile(iosPath: string, props: FishjamPluginOptions) {
52+
const podfileSnippet = getSbePodfileSnippet(props);
4353
let matches;
4454
try {
4555
const podfile = await fs.readFile(`${iosPath}/Podfile`, {
4656
encoding: 'utf-8',
4757
});
48-
matches = podfile.match(SBE_PODFILE_SNIPPET);
58+
matches = podfile.match(podfileSnippet);
4959
} catch (e) {
5060
console.error('Error reading from Podfile: ', e);
5161
}
5262

5363
if (matches) {
5464
console.log(
55-
`${SBE_TARGET_NAME} target already added to Podfile. Skipping...`,
65+
`${getSbeTargetName(props)} target already added to Podfile. Skipping...`,
5666
);
5767
return;
5868
}
5969
try {
60-
fs.appendFile(`${iosPath}/Podfile`, SBE_PODFILE_SNIPPET);
70+
fs.appendFile(`${iosPath}/Podfile`, podfileSnippet);
6171
} catch (e) {
6272
console.error('Error writing to Podfile: ', e);
6373
}
@@ -67,10 +77,15 @@ async function updatePodfile(iosPath: string) {
6777
* Adds "App Group" permission
6878
* App Group allow your app and the FishjamScreenBroadcastExtension to communicate with each other.
6979
*/
70-
const withAppGroupPermissions: ConfigPlugin = (config) => {
80+
const withAppGroupPermissions: ConfigPlugin<FishjamPluginOptions> = (
81+
config,
82+
props,
83+
) => {
7184
const APP_GROUP_KEY = 'com.apple.security.application-groups';
7285
const bundleIdentifier = config.ios?.bundleIdentifier || '';
73-
const groupIdentifier = `group.${bundleIdentifier}`;
86+
const groupIdentifier =
87+
props?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
88+
const mainTarget = props?.ios?.mainTargetName || '';
7489

7590
config.ios ??= {};
7691
config.ios.entitlements ??= {};
@@ -117,16 +132,13 @@ const withAppGroupPermissions: ConfigPlugin = (config) => {
117132
enabled: 1,
118133
};
119134

120-
const entitlementsFilePath = `${props.modRequest.projectName}/${props.modRequest.projectName}.entitlements`;
135+
const mainTargetName = mainTarget || props.modRequest.projectName;
136+
const entitlementsFilePath = `${mainTargetName}/${mainTargetName}.entitlements`;
121137
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
122138

123139
Object.keys(configurations).forEach((key) => {
124140
const config = configurations[key];
125-
if (
126-
config.buildSettings?.PRODUCT_NAME?.includes(
127-
props.modRequest.projectName,
128-
)
129-
) {
141+
if (config.buildSettings?.PRODUCT_NAME?.includes(mainTargetName)) {
130142
if (!config.buildSettings.CODE_SIGN_ENTITLEMENTS) {
131143
config.buildSettings.CODE_SIGN_ENTITLEMENTS = entitlementsFilePath;
132144
}
@@ -143,12 +155,17 @@ const withAppGroupPermissions: ConfigPlugin = (config) => {
143155
* Adds constants to Info.plist
144156
* In other to dynamically retreive extension's bundleId and group name we need to store it in Info.plist.
145157
*/
146-
const withInfoPlistConstants: ConfigPlugin = (config) =>
158+
const withInfoPlistConstants: ConfigPlugin<FishjamPluginOptions> = (
159+
config,
160+
props,
161+
) =>
147162
withInfoPlist(config, (configuration) => {
148163
const bundleIdentifier = configuration.ios?.bundleIdentifier || '';
149-
configuration.modResults['AppGroupName'] = `group.${bundleIdentifier}`;
164+
const groupIdentifier =
165+
props?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
166+
configuration.modResults['AppGroupName'] = groupIdentifier;
150167
configuration.modResults['ScreenShareExtensionBundleId'] =
151-
`${bundleIdentifier}.${SBE_TARGET_NAME}`;
168+
`${bundleIdentifier}.${getSbeTargetName(props)}`;
152169
return configuration;
153170
});
154171

@@ -161,7 +178,10 @@ const withFishjamSBE: ConfigPlugin<FishjamPluginOptions> = (config, options) =>
161178
const appName = props.modRequest.projectName || '';
162179
const iosPath = props.modRequest.platformProjectRoot;
163180
const bundleIdentifier = props.ios?.bundleIdentifier;
181+
const groupIdentifier =
182+
options?.ios?.appGroupContainerId || `group.${bundleIdentifier}`;
164183
const xcodeProject = props.modResults;
184+
const targetName = getSbeTargetName(options);
165185

166186
const pluginDir = require.resolve(
167187
'@fishjam-cloud/react-native-client/package.json',
@@ -171,12 +191,20 @@ const withFishjamSBE: ConfigPlugin<FishjamPluginOptions> = (config, options) =>
171191
'../plugin/broadcastExtensionFiles/',
172192
);
173193

174-
await updatePodfile(iosPath);
194+
await updatePodfile(iosPath, options);
175195

176196
const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
197+
const templateTargetName = 'FishjamScreenBroadcastExtension';
198+
177199
const extFiles = [
178200
'FishjamBroadcastSampleHandler.swift',
179-
`${SBE_TARGET_NAME}.entitlements`,
201+
`${templateTargetName}.entitlements`,
202+
`Info.plist`,
203+
];
204+
205+
const destFiles = [
206+
'FishjamBroadcastSampleHandler.swift',
207+
`${targetName}.entitlements`,
180208
`Info.plist`,
181209
];
182210

@@ -185,50 +213,48 @@ const withFishjamSBE: ConfigPlugin<FishjamPluginOptions> = (config, options) =>
185213
console.error(`Error parsing iOS project: ${JSON.stringify(err)}`);
186214
return;
187215
}
188-
189-
if (xcodeProject.pbxTargetByName(SBE_TARGET_NAME)) {
190-
console.log(
191-
`${SBE_TARGET_NAME} already exists in project. Skipping...`,
192-
);
216+
if (xcodeProject.pbxTargetByName(targetName)) {
217+
console.log(`${targetName} already exists in project. Skipping...`);
193218
return;
194219
}
195220
try {
196-
// copy extension files
197-
await fs.mkdir(`${iosPath}/${SBE_TARGET_NAME}`, { recursive: true });
221+
await fs.mkdir(`${iosPath}/${targetName}`, { recursive: true });
198222
for (let i = 0; i < extFiles.length; i++) {
199-
const extFile = extFiles[i];
200-
const targetFile = `${iosPath}/${SBE_TARGET_NAME}/${extFile}`;
201-
await fs.copyFile(`${extensionSourceDir}${extFile}`, targetFile);
223+
const srcFile = `${extensionSourceDir}${extFiles[i]}`;
224+
const destFile = `${iosPath}/${targetName}/${destFiles[i]}`;
225+
await fs.copyFile(srcFile, destFile);
202226
}
203227
} catch (e) {
204228
console.error('Error copying extension files: ', e);
205229
}
206230

207-
// update extension files
208231
await updateFileWithRegex(
209232
iosPath,
210-
`${SBE_TARGET_NAME}.entitlements`,
233+
`${targetName}.entitlements`,
211234
GROUP_IDENTIFIER_TEMPLATE_REGEX,
212-
`group.${bundleIdentifier}`,
235+
groupIdentifier,
236+
options,
213237
);
214238
await updateFileWithRegex(
215239
iosPath,
216240
'FishjamBroadcastSampleHandler.swift',
217241
GROUP_IDENTIFIER_TEMPLATE_REGEX,
218-
`group.${bundleIdentifier}`,
242+
groupIdentifier,
243+
options,
219244
);
220245
await updateFileWithRegex(
221246
iosPath,
222247
'FishjamBroadcastSampleHandler.swift',
223248
BUNDLE_IDENTIFIER_TEMPLATE_REGEX,
224249
bundleIdentifier || '',
250+
options,
225251
);
226252

227253
// Create new PBXGroup for the extension
228254
const extGroup = xcodeProject.addPbxGroup(
229255
extFiles,
230-
SBE_TARGET_NAME,
231-
SBE_TARGET_NAME,
256+
targetName,
257+
targetName,
232258
);
233259

234260
// Add the new PBXGroup to the top level group. This makes the
@@ -253,10 +279,10 @@ const withFishjamSBE: ConfigPlugin<FishjamPluginOptions> = (config, options) =>
253279
// Add the SBE target
254280
// This adds PBXTargetDependency and PBXContainerItemProxy for you
255281
const sbeTarget = xcodeProject.addTarget(
256-
SBE_TARGET_NAME,
282+
targetName,
257283
'app_extension',
258-
SBE_TARGET_NAME,
259-
`${bundleIdentifier}.${SBE_TARGET_NAME}`,
284+
targetName,
285+
`${bundleIdentifier}.${targetName}`,
260286
);
261287

262288
// Add build phases to the new target
@@ -290,16 +316,15 @@ const withFishjamSBE: ConfigPlugin<FishjamPluginOptions> = (config, options) =>
290316
for (const key in configurations) {
291317
if (
292318
typeof configurations[key].buildSettings !== 'undefined' &&
293-
configurations[key].buildSettings.PRODUCT_NAME ===
294-
`"${SBE_TARGET_NAME}"`
319+
configurations[key].buildSettings.PRODUCT_NAME === `"${targetName}"`
295320
) {
296321
const buildSettingsObj = configurations[key].buildSettings;
297322
buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
298323
options?.ios?.iphoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
299324
buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
300-
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${SBE_TARGET_NAME}/${SBE_TARGET_NAME}.entitlements`;
325+
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${targetName}/${targetName}.entitlements`;
301326
buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
302-
buildSettingsObj.INFOPLIST_FILE = `${SBE_TARGET_NAME}/Info.plist`;
327+
buildSettingsObj.INFOPLIST_FILE = `${targetName}/Info.plist`;
303328
buildSettingsObj.SWIFT_VERSION = '5.0';
304329
buildSettingsObj.MARKETING_VERSION = '1.0.0';
305330
buildSettingsObj.CURRENT_PROJECT_VERSION = '1';
@@ -335,8 +360,8 @@ const withFishjamPictureInPicture: ConfigPlugin<FishjamPluginOptions> = (
335360
*/
336361
const withFishjamIos: ConfigPlugin<FishjamPluginOptions> = (config, props) => {
337362
if (props?.ios?.enableScreensharing) {
338-
config = withAppGroupPermissions(config);
339-
config = withInfoPlistConstants(config);
363+
config = withAppGroupPermissions(config, props);
364+
config = withInfoPlistConstants(config, props);
340365
config = withFishjamSBE(config, props);
341366
}
342367
config = withPodfileProperties(config, (configuration) => {

0 commit comments

Comments
 (0)