All files / src/withPushNotifications withIosPushNotifications.utils.ts

100% Statements 37/37
88.88% Branches 16/18
100% Functions 8/8
100% Lines 37/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175                  4x             4x       12x 9x                                               4x       5x 1x 1x 1x 1x       4x                 4x       5x                         4x 5x 5x     5x           5x 7x         2x       5x               4x       1x   1x                 1x 6x 6x                   4x 5x 5x   5x 2x 2x 1x                   4x       5x             5x              
import { XcodeProject } from 'expo/config-plugins';
 
import {
  NS_ENTITLEMENTS_FILE_NAME,
  NS_FILES,
  NS_MAIN_FILE_NAME,
  NS_TARGET_NAME,
} from './withIosPushNotifications.constants';
 
const fs = require('fs');
 
/**
 * Create a file if it doesn't exist.
 * @param filePath - The path to the file
 * @param content - The content to write to the file
 */
export const createFileIfNoneExists = (
  filePath: string,
  content: string
): void => {
  if (!fs.existsSync(filePath)) {
    fs.writeFileSync(filePath, content);
  }
};
 
/**
 * Xcode build settings
 */
type BuildSettings = {
  SWIFT_VERSION?: string;
  CODE_SIGN_STYLE?: string;
  CODE_SIGN_IDENTITY?: string;
  OTHER_CODE_SIGN_FLAGS?: string;
  DEVELOPMENT_TEAM?: string;
  PROVISIONING_PROFILE_SPECIFIER?: string;
  PRODUCT_NAME?: string;
  CODE_SIGN_ENTITLEMENTS?: string;
};
 
/**
 * Retrieve Swift version and code signing settings from main target to apply to
 * dependency targets.
 * @param xcconfigs - Xcode project configuration
 * @returns Build settings
 */
export const extractBuildSettings = (
  xcconfigs: Record<string, any>
): BuildSettings => {
  let swiftVersion;
  for (const configUUID of Object.keys(xcconfigs)) {
    const buildSettings = xcconfigs[configUUID]?.buildSettings;
    Eif (!swiftVersion && buildSettings && buildSettings.SWIFT_VERSION) {
      swiftVersion = buildSettings.SWIFT_VERSION;
      return buildSettings;
    }
  }
 
  return { SWIFT_VERSION: swiftVersion };
};
 
/**
 * Add the notification service target to the Xcode project
 * @param xcodeProject - The Xcode project
 * @param bundleIdentifier - The bundle identifier
 * @returns The target
 */
export const addNotificationServiceTarget = (
  xcodeProject: XcodeProject,
  bundleIdentifier: string
) => {
  return xcodeProject.addTarget(
    NS_TARGET_NAME,
    'app_extension',
    NS_TARGET_NAME,
    `${bundleIdentifier}.${NS_TARGET_NAME}`
  );
};
 
/**
 * Add the notification service group to the Xcode project
 * @param xcodeProject - The Xcode project
 * @returns The group
 */
export const addNotificationServiceGroup = (xcodeProject: XcodeProject) => {
  const objects = xcodeProject.hash.project.objects;
  const groups = objects.PBXGroup;
 
  // Add the relevant files to the PBX group.
  const itblNotificationServiceGroup = xcodeProject.addPbxGroup(
    NS_FILES,
    NS_TARGET_NAME,
    NS_TARGET_NAME
  );
 
  for (const groupUUID of Object.keys(groups)) {
    if (
      typeof groups[groupUUID] === 'object' &&
      groups[groupUUID].name === undefined &&
      groups[groupUUID].path === undefined
    ) {
      xcodeProject.addToPbxGroup(itblNotificationServiceGroup.uuid, groupUUID);
    }
  }
 
  return itblNotificationServiceGroup;
};
 
/**
 * Apply the build settings to the notification service target
 * @param currentBuildSettings - The current build settings
 * @param newBuildSettings - The new build settings
 */
const applyBuildSettings = (
  currentBuildSettings: BuildSettings,
  newBuildSettings: BuildSettings
) => {
  currentBuildSettings.CODE_SIGN_ENTITLEMENTS = `${NS_TARGET_NAME}/${NS_ENTITLEMENTS_FILE_NAME}`;
 
  const valuesToUpdate = [
    'SWIFT_VERSION',
    'CODE_SIGN_STYLE',
    'CODE_SIGN_IDENTITY',
    'OTHER_CODE_SIGN_FLAGS',
    'DEVELOPMENT_TEAM',
    'PROVISIONING_PROFILE_SPECIFIER',
  ] as (keyof BuildSettings)[];
 
  valuesToUpdate.forEach((value) => {
    Eif (newBuildSettings[value]) {
      currentBuildSettings[value] = newBuildSettings[value];
    }
  });
};
 
/**
 * Update the build settings for the notification service target
 * @param xcodeProject - The Xcode project
 * @param buildSettings - The build settings
 */
export const updateBuildSettings = (xcodeProject: XcodeProject) => {
  const xcconfigs = xcodeProject.hash.project.objects.XCBuildConfiguration;
  const newBuildSettings = extractBuildSettings(xcconfigs);
 
  for (const configUUID of Object.keys(xcconfigs)) {
    const buildSettings = xcconfigs[configUUID].buildSettings;
    if (buildSettings && buildSettings.PRODUCT_NAME === `"${NS_TARGET_NAME}"`) {
      applyBuildSettings(buildSettings, newBuildSettings);
    }
  }
};
 
/**
 * Add the build phases for the notification service target
 * @param xcodeProject - The Xcode project
 * @param targetUUID - The target UUID
 */
export const addBuildPhases = (
  xcodeProject: XcodeProject,
  targetUUID: string
) => {
  xcodeProject.addBuildPhase(
    [NS_MAIN_FILE_NAME],
    'PBXSourcesBuildPhase',
    'Sources',
    targetUUID
  );
 
  xcodeProject.addBuildPhase(
    ['UserNotifications.framework'],
    'PBXFrameworksBuildPhase',
    'Frameworks',
    targetUUID
  );
};