public void AddAppExtensionOutputIsExpected() { ResetGuidGenerator(); PBXProject proj = ReadPBXProject(); proj.AddBuildConfig("Debug"); string target = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); proj.AddAppExtension(target, "App Extension", "com.company.product.appextension", "App Extension/Info.plist"); TestOutput(proj, "add_app_extension.pbxproj"); }
/// <summary> /// Create and add the notification extension to the project /// </summary> private void AddNotificationServiceExtension() { #if !UNITY_CLOUD_BUILD // refresh plist and podfile on appends ExtensionCreatePlist(_outputPath); ExtensionAddPodsToTarget(); var extensionGuid = _project.TargetGuidByName(ServiceExtensionTargetName); // skip target setup if already present if (!string.IsNullOrEmpty(extensionGuid)) { return; } extensionGuid = _project.AddAppExtension(_project.GetMainTargetGuid(), ServiceExtensionTargetName, PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.iOS) + "." + ServiceExtensionTargetName, ServiceExtensionTargetName + "/" + "Info.plist" // Unix path as it's used by Xcode ); ExtensionAddSourceFiles(extensionGuid); // Makes it so that the extension target is Universal (not just iPhone) and has an iOS 10 deployment target _project.SetBuildProperty(extensionGuid, "TARGETED_DEVICE_FAMILY", "1,2"); _project.SetBuildProperty(extensionGuid, "IPHONEOS_DEPLOYMENT_TARGET", "10.0"); _project.SetBuildProperty(extensionGuid, "SWIFT_VERSION", "5.0"); _project.SetBuildProperty(extensionGuid, "ARCHS", "arm64"); _project.SetBuildProperty(extensionGuid, "DEVELOPMENT_TEAM", PlayerSettings.iOS.appleDeveloperTeamID); _project.AddBuildProperty(extensionGuid, "LIBRARY_SEARCH_PATHS", $"$(PROJECT_DIR)/Libraries/{PluginLibrariesPath.Replace("\\", "/")}"); _project.WriteToFile(_projectPath); // add capabilities + entitlements var entitlementsPath = GetEntitlementsPath(extensionGuid, ServiceExtensionTargetName); var projCapability = new ProjectCapabilityManager(_projectPath, entitlementsPath, ServiceExtensionTargetName); projCapability.AddAppGroups(new[] { _appGroupName }); projCapability.WriteToFile(); #endif }
public static void OnPostProcessEnableNotificationExtension( BuildTarget buildTarget, string buildPath) { if (!InitialisationHelper.IsDevelopment() || !InitialisationHelper.IsDebugNotifications()) { return; } Debug.Log("Adding DDNA debug notification content extension into XCode Project"); PBXProject proj = new PBXProject(); string projPath = PBXProject.GetPBXProjectPath(buildPath); proj.ReadFromFile(projPath); #if UNITY_2019_3_OR_NEWER string mainTarget = proj.GetUnityFrameworkTargetGuid(); #else string mainTarget = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); #endif string srcPath = Application.dataPath + "/DeltaDNA/Ads/Editor/iOS/NotificationContent/"; string destPath = buildPath + "/Notification Content/"; FileUtil.CopyFileOrDirectory(srcPath, destPath); string newTarget = proj.AddAppExtension(mainTarget, "Notification Content", PlayerSettings.applicationIdentifier + ".ddna-debug-ext", "Notification Content/Info.plist"); proj.AddFileToBuild(newTarget, proj.AddFile(destPath + "NotificationViewController.h", "Notification Content/NotificationViewController.h")); proj.AddFileToBuild(newTarget, proj.AddFile(destPath + "NotificationViewController.m", "Notification Content/NotificationViewController.m")); proj.AddFileToBuild(newTarget, proj.AddFile(destPath + "Info.plist", "Notification Content/Info.plist")); proj.AddFileToBuild(newTarget, proj.AddFile(destPath + "Base.lproj/MainInterface.storyboard", "Notification Content/MainInterface.storyboard")); proj.AddFrameworkToProject(newTarget, "UserNotificationsUI.framework", true); proj.AddFrameworkToProject(newTarget, "UserNotifications.framework", true); // link in the code from the Pods library string podPath = buildPath + "/Pods/DeltaDNADebug/DeltaDNADebug/"; proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Classes/DDNADebugNotificationViewController.h", "Notification Content/DDNADebugNotificationViewController.h")); proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Classes/DDNADebugNotificationViewController.m", "Notification Content/DDNADebugNotificationViewController.m")); proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Classes/DDNADebugContentViewController.h", "Notification Content/DDNADebugContentViewController.h")); proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Classes/DDNADebugContentViewController.m", "Notification Content/DDNADebugContentViewController.m")); proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Assets/DebugInterface.storyboard", "Notification Content/DebugInterface.storyboard")); proj.SetCompileFlagsForFile(newTarget, proj.FindFileGuidByProjectPath("Notification Content/DDNADebugContentViewController.m"), new List <string> { "-fobjc-arc" }); proj.SetTeamId(newTarget, PlayerSettings.iOS.appleDeveloperTeamID); proj.SetBuildProperty(newTarget, "IPHONEOS_DEPLOYMENT_TARGET", PlayerSettings.iOS.targetOSVersionString); proj.SetBuildProperty(newTarget, "ONLY_ACTIVE_ARCH", "NO"); proj.UpdateBuildProperty(newTarget, "ARCHS", new string[] { "armv7", "arm64" }, new string[] {}); // Update the search paths proj.SetBuildProperty(newTarget, "CLANG_ENABLE_MODULES", "YES"); proj.AddBuildProperty(newTarget, "OTHER_LDFLAGS", "$(inherited)"); proj.AddBuildProperty(newTarget, "OTHER_CFLAGS", "$(inherited)"); proj.AddBuildProperty(newTarget, "HEADER_SEARCH_PATHS", "$(inherited)"); proj.AddBuildProperty(newTarget, "HEADER_SEARCH_PATHS", "$(PROJECT_DIR)/Pods/Headers/Public"); proj.AddBuildProperty(newTarget, "FRAMEWORK_SEARCH_PATHS", "$(inherited)"); proj.AddBuildProperty(newTarget, "FRAMEWORK_SEARCH_PATHS", "$(PROJECT_DIR)/Frameworks"); proj.AddBuildProperty(newTarget, "LIBRARY_SEARCH_PATHS", "$(inherited)"); proj.AddBuildProperty(newTarget, "OTHER_LDFLAGS", "-ObjC"); // Add preprocessor defines string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup); List <string> allDefines = definesString.Split(';').Where(i => i.Length > 0).Select(i => string.Format("{0}=1", i)).ToList(); allDefines.Add("$(inherited)"); allDefines.Reverse(); proj.UpdateBuildProperty(newTarget, "GCC_PREPROCESSOR_DEFINITIONS", allDefines, new string [] {}); proj.WriteToFile(projPath); }
private static void PostProcessBuild_iOS(BuildTarget target, string buildPath) { if (target != BuildTarget.iOS) { return; } //Copy files to xcode project dir Directory.CreateDirectory(buildPath + "/NotificationService"); //string[] filesToCopy = ["Info.plist", "NotificationService.entitlements", ]; File.Copy("Assets/NotificationService/NotificationService.h", buildPath + "/NotificationService/NotificationService.h"); File.Copy("Assets/NotificationService/NotificationService.m", buildPath + "/NotificationService/NotificationService.m"); File.Copy("Assets/NotificationService/Info.plist", buildPath + "/NotificationService/Info.plist"); //load xcode project PBXProject proj = new PBXProject(); string projPath = PBXProject.GetPBXProjectPath(buildPath); proj.ReadFromFile(projPath); string mainTarget = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); //Try to retreive bundleId from xcode project string bundleId = null; string infoPlistPath = "Info.plist"; try { infoPlistPath = proj.GetBuildPropertyForAnyConfig(mainTarget, "INFOPLIST_FILE"); } catch (Exception e) { Debug.Log("Can't load Info.plist location: " + e); } try { PlistDocument infoPlist = new PlistDocument(); infoPlist.ReadFromFile(buildPath + "/" + infoPlistPath); bundleId = infoPlist.root.values["CFBundleIdentifier"].AsString(); Regex configParamsMatcher = new Regex(@"\$\{([\w_]*)\}"); MatchCollection matches = configParamsMatcher.Matches(bundleId); bundleId = configParamsMatcher.Replace(bundleId, (match) => { return(proj.GetBuildPropertyForAnyConfig(mainTarget, match.Groups[1].Value)); }); } catch (Exception e) { Debug.Log("Can't load BundleId: " + e); if (String.IsNullOrEmpty(bundleId)) { bundleId = "com.unity3d.product"; } } //Try to retrieve archs string archs = proj.GetBuildPropertyForAnyConfig(mainTarget, "ARCHS"); //Add extension string newTarget = proj.AddAppExtension(mainTarget, "NotificationService", bundleId + ".NotificationService", "NotificationService/Info.plist"); proj.AddFileToBuild(newTarget, proj.AddFile(buildPath + "/NotificationService/NotificationService.h", "NotificationService/NotificationService.h")); proj.AddFileToBuild(newTarget, proj.AddFile(buildPath + "/NotificationService/NotificationService.m", "NotificationService/NotificationService.m")); proj.SetBuildProperty(newTarget, "IPHONEOS_DEPLOYMENT_TARGET", "10.0"); proj.SetBuildProperty(newTarget, "ARCHS", archs); proj.AddFrameworkToProject(newTarget, "UserNotifications.framework", false); proj.WriteToFile(projPath); }
static void AddNotificationExtension(PBXProject project, string projectPath) { #if UNITY_2018_1_OR_NEWER const string extensionName = "/GetSocialNotificationExtension"; if (!Directory.Exists(projectPath + extensionName)) { Directory.CreateDirectory(projectPath + extensionName); } var pluginDir = GetSocialSettings.GetPluginPath(); PlistDocument notificationServicePlist = new PlistDocument(); notificationServicePlist.ReadFromFile(pluginDir + "/Editor/iOS/Helpers/NotificationService/Info.plist"); notificationServicePlist.root.SetString("CFBundleShortVersionString", PlayerSettings.bundleVersion); notificationServicePlist.root.SetString("CFBundleVersion", PlayerSettings.iOS.buildNumber); notificationServicePlist.WriteToFile(projectPath + "/GetSocialNotificationExtension/Info.plist"); var extensionServiceSourceHeaderFile = pluginDir + "/Editor/iOS/Helpers/NotificationService/GetSocialNotificationService.h"; var extensionServiceSourceImpFile = pluginDir + "/Editor/iOS/Helpers/NotificationService/GetSocialNotificationService.m"; var extensionServiceTargetHeaderFile = "GetSocialNotificationExtension/GetSocialNotificationService.h"; var extensionServiceTargetImpFile = "GetSocialNotificationExtension/GetSocialNotificationService.m"; File.Copy(extensionServiceSourceHeaderFile, projectPath + "/" + extensionServiceTargetHeaderFile, true); File.Copy(extensionServiceSourceImpFile, projectPath + "/" + extensionServiceTargetImpFile, true); var mainTarget = project.TargetGuidByName(PBXProject.GetUnityTargetName()); var appExtensionTarget = project.AddAppExtension(mainTarget, "GetSocialNotificationExtension", projectPath + "/GetSocialNotificationExtension/Info.plist"); project.AddFileToBuild(appExtensionTarget, project.AddFile(extensionServiceTargetHeaderFile, extensionServiceTargetHeaderFile)); project.AddFileToBuild(appExtensionTarget, project.AddFile(extensionServiceTargetImpFile, extensionServiceTargetImpFile)); var frameworksPath = GetSocialSettings.GetPluginPath().Substring(GetSocialSettings.GetPluginPath().IndexOf("/") + 1); var relativeExtensionFrameworkPath = "Frameworks/" + frameworksPath + "/Plugins/iOS/GetSocialNotificationExtension.framework"; project.AddFileToBuild(appExtensionTarget, project.FindFileGuidByProjectPath(relativeExtensionFrameworkPath)); var deviceFamily = ""; switch (PlayerSettings.iOS.targetDevice) { case iOSTargetDevice.iPhoneOnly: deviceFamily = "1"; break; case iOSTargetDevice.iPadOnly: deviceFamily = "2"; break; case iOSTargetDevice.iPhoneAndiPad: deviceFamily = "1,2"; break; } project.SetBuildProperty(appExtensionTarget, "TARGETED_DEVICE_FAMILY", deviceFamily); if (double.Parse(PlayerSettings.iOS.targetOSVersionString) > 10) { project.SetBuildProperty(appExtensionTarget, "IPHONEOS_DEPLOYMENT_TARGET", PlayerSettings.iOS.targetOSVersionString.ToString()); } else { project.SetBuildProperty(appExtensionTarget, "IPHONEOS_DEPLOYMENT_TARGET", "10.0"); } project.SetBuildProperty(appExtensionTarget, "DEVELOPMENT_TEAM", PlayerSettings.iOS.appleDeveloperTeamID); project.SetBuildProperty(appExtensionTarget, "PRODUCT_BUNDLE_IDENTIFIER", GetSocialSettings.ExtensionBundleId); project.SetBuildProperty(appExtensionTarget, "CODE_SIGN_STYLE", PlayerSettings.iOS.appleEnableAutomaticSigning ? "Automatic" : "Manual"); if (!PlayerSettings.iOS.appleEnableAutomaticSigning) { if (GetSocialSettings.ExtensionProvisioningProfile.Length == 0) { Debug.LogError("Notification Extension Provisioning Profile must be specified."); } else { project.SetBuildProperty(appExtensionTarget, "PROVISIONING_PROFILE", GetSocialSettings.ExtensionProvisioningProfile); project.SetBuildProperty(appExtensionTarget, "PROVISIONING_PROFILE_SPECIFIER", GetSocialSettings.ExtensionProvisioningProfile); } } project.AddFrameworkToProject(mainTarget, "UserNotifications.framework", false); AddExtensionEntitlements(projectPath, project, appExtensionTarget); #endif }
// Enables Advanced Push Capabilities private static PBXProject AddExtensionToProject(PBXProject project, string pathToProject) { PBXProject proj = project; #if UNITY_2019_3_OR_NEWER string mainTarget = proj.GetUnityMainTargetGuid(); #else string mainTarget = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); #endif // Add Push files to the extension CopyFolder("Assets/Plugins/iOS/SwrvePushExtension", pathToProject + "/SwrvePushExtension"); string extensionTarget = proj.AddAppExtension(mainTarget, "SwrvePushExtension", PlayerSettings.applicationIdentifier + ".ServiceExtension", "SwrvePushExtension/Info.plist"); // Ensure Service Files are part of the Build Phases proj.AddFile(pathToProject + "/SwrvePushExtension/NotificationService.h", "SwrvePushExtension/NotificationService.h"); proj.AddFileToBuild(extensionTarget, proj.AddFile(pathToProject + "/SwrvePushExtension/NotificationService.m", "SwrvePushExtension/NotificationService.m")); // Add TeamID from Player Settings to project proj.SetTeamId(extensionTarget, PlayerSettings.iOS.appleDeveloperTeamID); // Add Extension Common if (!AddFolderToProject(proj, extensionTarget, "Assets/Plugins/iOS/SwrveSDKCommon", pathToProject, "SwrvePushExtension/SwrveSDKCommon")) { UnityEngine.Debug.LogError("Swrve SDK - Could not find the Common folder in the extension. If you want to use Rich Push please contact [email protected]"); } // Add Frameworks needed for SwrveSDKCommon proj.AddFrameworkToProject(extensionTarget, "AudioToolbox.framework", false /*weak*/); proj.AddFrameworkToProject(extensionTarget, "AVFoundation.framework", true /*weak*/); proj.AddFrameworkToProject(extensionTarget, "CFNetwork.framework", false /*weak*/); proj.AddFrameworkToProject(extensionTarget, "CoreGraphics.framework", false /*weak*/); proj.AddFrameworkToProject(extensionTarget, "CoreMedia.framework", false /*weak*/); proj.AddFrameworkToProject(extensionTarget, "CoreMotion.framework", false /*weak*/); proj.AddFrameworkToProject(extensionTarget, "CoreVideo.framework", false /*weak*/); proj.AddFrameworkToProject(extensionTarget, "CoreTelephony.framework", false /*weak*/); proj.AddFrameworkToProject(extensionTarget, "Foundation.framework", false /*not weak*/); proj.AddFrameworkToProject(extensionTarget, "iAd.framework", false /*weak*/); proj.AddFrameworkToProject(extensionTarget, "MediaPlayer.framework", true /*weak*/); proj.AddFrameworkToProject(extensionTarget, "UIKit.framework", true /*weak*/); proj.AddFrameworkToProject(extensionTarget, "AdSupport.framework", false /*not weak*/); // Add Notification Frameworks proj.AddFrameworkToProject(extensionTarget, "UserNotifications.framework", false /*not weak*/); proj.AddFrameworkToProject(extensionTarget, "UserNotificationsUI.framework", false /*not weak*/); // Update Build Settings for Compatibility proj.AddBuildProperty(extensionTarget, "CLANG_ENABLE_OBJC_ARC", "YES"); proj.AddBuildProperty(extensionTarget, "IPHONEOS_DEPLOYMENT_TARGET", "10.0"); proj.AddBuildProperty(extensionTarget, "TARGETED_DEVICE_FAMILY", "1,2"); proj.AddBuildProperty(extensionTarget, "ARCHS", "$(ARCHS_STANDARD)"); // Add appgroupconfig.json to XCode project string appGroupIndentifier = SwrveBuildComponent.GetPostProcessString(SwrveBuildComponent.APP_GROUP_ID_KEY); string appGroupConfig = "appgroupconfig.json"; // Add the app group config so it can be read at run-time by the main app and the service extension SwrveBuildComponent.SetAppGroupConfigKey("ios", Path.Combine(pathToProject + "/SwrvePushExtension", appGroupConfig)); proj.AddFileToBuild(extensionTarget, proj.AddFile(pathToProject + "/SwrvePushExtension/" + appGroupConfig, "SwrvePushExtension/" + appGroupConfig)); proj.AddFileToBuild(mainTarget, proj.AddFile(pathToProject + "/SwrvePushExtension/" + appGroupConfig, "SwrvePushExtension/" + appGroupConfig)); // Edit template entitlements file string entitlementContents = File.ReadAllText(pathToProject + "/SwrvePushExtension/SwrvePushExtension.entitlements"); entitlementContents = entitlementContents.Replace("<string>APP_GROUP_TEMP</string>", "<string>" + appGroupIndentifier + "</string>"); File.WriteAllText(pathToProject + "/SwrvePushExtension/SwrvePushExtension.entitlements", entitlementContents); // Add entitlements file to service extension proj.AddFileToBuild(extensionTarget, proj.AddFile(pathToProject + "/SwrvePushExtension/SwrvePushExtension.entitlements", "SwrvePushExtension/SwrvePushExtension.entitlements")); proj.AddCapability(extensionTarget, PBXCapabilityType.AppGroups, "SwrvePushExtension/SwrvePushExtension.entitlements", false); // Return edited project return(proj); }
public static void OnPostProcessEnableNotificationExtension( BuildTarget buildTarget, string buildPath) { if (!Editor.InitialisationHelper.IsDevelopment() || !Editor.InitialisationHelper.IsDebugNotifications()) { return; } Debug.Log("Adding DDNA debug notification content extension into XCode Project"); string unityPlugin = buildPath + "/Libraries/DeltaDNAAds/Plugins/iOS/DDNADebugUnityPlugin.mm"; File.WriteAllText( unityPlugin, File.ReadAllText(unityPlugin).Replace( "//IMPL_APP_CONTROLLER_SUBCLASS(DDNAUnityAppController)", "IMPL_APP_CONTROLLER_SUBCLASS(DDNAUnityAppController)")); PBXProject proj = new PBXProject(); string projPath = PBXProject.GetPBXProjectPath(buildPath); proj.ReadFromFile(projPath); string mainTarget = proj.TargetGuidByName(PBXProject.GetUnityTargetName()); string srcPath = Application.dataPath + "/DeltaDNAAds/Editor/iOS/NotificationContent/"; string destPath = buildPath + "/Notification Content/"; FileUtil.CopyFileOrDirectory(srcPath, destPath); string newTarget = proj.AddAppExtension(mainTarget, "Notification Content", PlayerSettings.applicationIdentifier + ".ddna-debug-ext", "Notification Content/Info.plist"); proj.AddFileToBuild(newTarget, proj.AddFile(destPath + "NotificationViewController.h", "Notification Content/NotificationViewController.h")); proj.AddFileToBuild(newTarget, proj.AddFile(destPath + "NotificationViewController.m", "Notification Content/NotificationViewController.m")); proj.AddFileToBuild(newTarget, proj.AddFile(destPath + "Info.plist", "Notification Content/Info.plist")); proj.AddFileToBuild(newTarget, proj.AddFile(destPath + "Base.lproj/MainInterface.storyboard", "Notification Content/MainInterface.storyboard")); proj.AddFrameworkToProject(newTarget, "UserNotificationsUI.framework", true); proj.AddFrameworkToProject(newTarget, "UserNotifications.framework", true); // link in the code from the Pods library string podPath = buildPath + "/Pods/DeltaDNADebug/DeltaDNADebug/"; proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Classes/DDNADebugNotificationViewController.h", "Notification Content/DDNADebugNotificationViewController.h")); proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Classes/DDNADebugNotificationViewController.m", "Notification Content/DDNADebugNotificationViewController.m")); proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Classes/DDNADebugContentViewController.h", "Notification Content/DDNADebugContentViewController.h")); proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Classes/DDNADebugContentViewController.m", "Notification Content/DDNADebugContentViewController.m")); proj.AddFileToBuild(newTarget, proj.AddFile(podPath + "Assets/DebugInterface.storyboard", "Notification Content/DebugInterface.storyboard")); proj.SetCompileFlagsForFile(newTarget, proj.FindFileGuidByProjectPath("Notification Content/DDNADebugContentViewController.m"), new List <string> { "-fobjc-arc" }); proj.SetTeamId(newTarget, PlayerSettings.iOS.appleDeveloperTeamID); proj.SetBuildProperty(newTarget, "IPHONEOS_DEPLOYMENT_TARGET", PlayerSettings.iOS.targetOSVersionString); proj.SetBuildProperty(newTarget, "ONLY_ACTIVE_ARCH", "NO"); proj.UpdateBuildProperty(newTarget, "ARCHS", new string[] { "armv7", "arm64" }, new string[] {}); // Update the search paths proj.SetBuildProperty(newTarget, "CLANG_ENABLE_MODULES", "YES"); proj.AddBuildProperty(newTarget, "OTHER_LDFLAGS", "$(inherited)"); proj.AddBuildProperty(newTarget, "OTHER_CFLAGS", "$(inherited)"); proj.AddBuildProperty(newTarget, "HEADER_SEARCH_PATHS", "$(inherited)"); proj.AddBuildProperty(newTarget, "HEADER_SEARCH_PATHS", "$(PROJECT_DIR)/Pods/Headers/Public"); proj.AddBuildProperty(newTarget, "FRAMEWORK_SEARCH_PATHS", "$(inherited)"); proj.AddBuildProperty(newTarget, "FRAMEWORK_SEARCH_PATHS", "$(PROJECT_DIR)/Frameworks"); proj.AddBuildProperty(newTarget, "LIBRARY_SEARCH_PATHS", "$(inherited)"); proj.AddBuildProperty(newTarget, "OTHER_LDFLAGS", "-ObjC"); proj.WriteToFile(projPath); }