diff --git a/Assets/Plugins/Android/appboy-ui.aar b/Assets/Plugins/Android/appboy-ui.aar index 5a5d6bfc..7a9dc1d7 100644 Binary files a/Assets/Plugins/Android/appboy-ui.aar and b/Assets/Plugins/Android/appboy-ui.aar differ diff --git a/Assets/Plugins/Android/appboy.aar b/Assets/Plugins/Android/appboy.aar index 005d03ba..1cbae860 100644 Binary files a/Assets/Plugins/Android/appboy.aar and b/Assets/Plugins/Android/appboy.aar differ diff --git a/Assets/Plugins/Appboy/Editor/AppboyConfig.cs b/Assets/Plugins/Appboy/Editor/AppboyConfig.cs index 030d235f..a03de6f4 100644 --- a/Assets/Plugins/Appboy/Editor/AppboyConfig.cs +++ b/Assets/Plugins/Appboy/Editor/AppboyConfig.cs @@ -74,6 +74,8 @@ public class AppboyConfig : ScriptableObject { [SerializeField] private bool iOSPushIsBackgroundEnabled = false; [SerializeField] + private string iOSEntitlementsFilePath = string.Empty; + [SerializeField] private string iOSPushReceivedGameObjectName = string.Empty; [SerializeField] private string iOSPushReceivedCallbackMethodName = string.Empty; @@ -125,6 +127,8 @@ public class AppboyConfig : ScriptableObject { private string iOSInAppMessageCallbackMethodName = string.Empty; [SerializeField] private bool iOSDisplayInAppMessages = false; + [SerializeField] + private int iOSInitialInAppMessageOperation = 0; // Android [SerializeField] private string androidInAppMessageListenerGameObjectName = string.Empty; @@ -271,6 +275,11 @@ public static bool IOSPushIsBackgroundEnabled { set { SetProperty(ref Instance.iOSPushIsBackgroundEnabled, value); } } + public static string IOSEntitlementsFilePath { + get { return Instance.iOSEntitlementsFilePath; } + set { SetProperty(ref Instance.iOSEntitlementsFilePath, value); } + } + // In-App Messages public static string IOSInAppMessageGameObjectName { get { return Instance.iOSInAppMessageGameObjectName; } @@ -287,6 +296,11 @@ public static bool IOSDisplayInAppMessages { set { SetProperty(ref Instance.iOSDisplayInAppMessages, value); } } + public static int IOSInitialInAppMessageOperation { + get { return Instance.iOSInitialInAppMessageOperation; } + set { SetProperty(ref Instance.iOSInitialInAppMessageOperation, value); } + } + // News Feed public static string IOSFeedGameObjectName { get { return Instance.iOSFeedGameObjectName; } diff --git a/Assets/Plugins/Appboy/Editor/AppboyConfigEditor.cs b/Assets/Plugins/Appboy/Editor/AppboyConfigEditor.cs index 4983d111..128f5d46 100644 --- a/Assets/Plugins/Appboy/Editor/AppboyConfigEditor.cs +++ b/Assets/Plugins/Appboy/Editor/AppboyConfigEditor.cs @@ -8,7 +8,7 @@ public class AppboyConfigEditor : EditorWindow { private Vector2 scrollPosition; private GUILayoutOption[] buttonGuiStyle = new GUILayoutOption[] { GUILayout.ExpandWidth(true) }; // https://braze-inc.github.io/braze-android-sdk/kdoc/braze-android-sdk/com.braze.ui.inappmessage/-in-app-message-operation/index.html - private string[] ANDROID_IAM_OPERATIONS = new string[] {"Display Now", "Display Later", "Discard"}; + private string[] IAM_OPERATIONS = new string[] {"Display Now", "Display Later", "Discard"}; // Cross-platform settings private bool generalShowAllSettings = true; @@ -135,6 +135,7 @@ private void IOSBuildGUI() { if (!String.IsNullOrEmpty(AppboyConfig.IOSInAppMessageGameObjectName.Trim()) && !String.IsNullOrEmpty(AppboyConfig.IOSInAppMessageCallbackMethodName.Trim())) { AppboyConfig.IOSDisplayInAppMessages = EditorGUILayout.ToggleLeft(" Braze Displays In-App Messages", AppboyConfig.IOSDisplayInAppMessages); } + AppboyConfig.IOSInitialInAppMessageOperation = EditorGUILayout.Popup("In App Message Manager Initial Display Operation", AppboyConfig.IOSInitialInAppMessageOperation, IAM_OPERATIONS); EditorGUI.indentLevel--; } EditorGUI.indentLevel--; @@ -204,6 +205,9 @@ private void IOSBuildGUIPush() { AppboyConfig.IOSPushIsBackgroundEnabled = EditorGUILayout.ToggleLeft(" Enable Background Push", AppboyConfig.IOSPushIsBackgroundEnabled); EditorGUILayout.LabelField("Allows the system to wake your app from suspension when a push notification arrives.", EditorStyles.wordWrappedMiniLabel); + AppboyConfig.IOSEntitlementsFilePath = EditorGUILayout.TextField("Entitlements File Path", AppboyConfig.IOSEntitlementsFilePath); + EditorGUILayout.LabelField("If you already have an entitlements file setup in your application, provide its file path relative to the root of the generated Xcode project here. Otherwise, leave this field empty.", EditorStyles.wordWrappedMiniLabel); + showPushReceivedListener = EditorGUILayout.Foldout(showPushReceivedListener, "Set Push Received Listener"); if (showPushReceivedListener) { EditorGUI.indentLevel++; @@ -348,7 +352,7 @@ private void AndroidBuildGUIInAppMessages() { EditorGUI.indentLevel--; } - AppboyConfig.AndroidInitialInAppMessageOperation = EditorGUILayout.Popup("In App Message Manager Initial Display Operation", AppboyConfig.AndroidInitialInAppMessageOperation, ANDROID_IAM_OPERATIONS); + AppboyConfig.AndroidInitialInAppMessageOperation = EditorGUILayout.Popup("In App Message Manager Initial Display Operation", AppboyConfig.AndroidInitialInAppMessageOperation, IAM_OPERATIONS); AppboyConfig.AndroidTriggerActionMinimumTimeSeconds = EditorGUILayout.TextField("Trigger Action Minimum Time (seconds)", AppboyConfig.AndroidTriggerActionMinimumTimeSeconds); } diff --git a/Assets/Plugins/Appboy/Editor/PostBuild.cs b/Assets/Plugins/Appboy/Editor/PostBuild.cs index fc3ba889..50a3e320 100644 --- a/Assets/Plugins/Appboy/Editor/PostBuild.cs +++ b/Assets/Plugins/Appboy/Editor/PostBuild.cs @@ -4,14 +4,19 @@ using System.Text.RegularExpressions; using UnityEngine; using UnityEditor; -using UnityEditor.Callbacks; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; using UnityEditor.iOS.Xcode; using UnityEditor.iOS.Xcode.Extensions; #endif namespace Appboy.Editor { +#if UNITY_IOS + public class PostBuild: IPostprocessBuildWithReport +#else public class PostBuild +#endif { #if UNITY_IOS private const string AppboyAppDelegatePath = "Libraries/Plugins/iOS/AppboyAppDelegate.mm"; @@ -33,6 +38,7 @@ public class PostBuild private const string BRZUnityPushOpenedCallbackKey = "PushOpenedCallbackMethodName"; private const string BRZUnityInAppMessageGameObjectKey = "InAppMessageGameObjectName"; private const string BRZUnityInAppMessageCallbackKey = "InAppMessageCallbackMethodName"; + private const string BRZUnityInAppMessageInitialOperation = "InAppMessageInitialOperation"; private const string BRZUnityFeedGameObjectKey = "FeedGameObjectName"; private const string BRZUnityFeedCallbackKey = "FeedCallbackMethodName"; private const string BRZUnityContentCardsGameObjectKey = "ContentCardsGameObjectName"; @@ -43,11 +49,16 @@ public class PostBuild private const string BRZUnityFeatureFlagsGameObjectKey = "FeatureFlagsGameObjectName"; private const string BRZUnityFeatureFlagsCallbackKey = "FeatureFlagsCallbackMethodName"; - [PostProcessBuildAttribute(1)] - public static void OnPostprocessBuild(BuildTarget target, string path) { - if (target == BuildTarget.iOS) { - ModifyPlist(path + PlistSubpath); - ModifyProject(path); + public int callbackOrder + { + get { return 10000; } + } + + public void OnPostprocessBuild(BuildReport report) + { + if (report.summary.platform == BuildTarget.iOS) { + ModifyPlist(report.summary.outputPath + PlistSubpath); + ModifyProject(report.summary.outputPath); } } @@ -64,6 +75,8 @@ private static void ModifyProject(string path) { } else { string mainTarget = project.GetUnityMainTargetGuid(); + + // - Add Push entitlement if (AppboyConfig.IOSIntegratesPush && !AppboyConfig.IOSDisableAutomaticPushCapability) { AddPushEntitlement( path, @@ -83,7 +96,7 @@ private static void ModifyProject(string path) { /****** Unity-iPhone (main target) ******/ // - Add packages via SPM - string brazeGUID = project.AddRemotePackageReferenceAtVersionUpToNextMinor("https://github.com/braze-inc/braze-swift-sdk-prebuilt-dynamic", "7.7.0"); + string brazeGUID = project.AddRemotePackageReferenceAtVersionUpToNextMinor("https://github.com/braze-inc/braze-swift-sdk-prebuilt-dynamic", "9.0.0"); project.AddRemotePackageFrameworkToProject(mainTarget, "BrazeKit", brazeGUID, false); project.AddRemotePackageFrameworkToProject(mainTarget, "BrazeUI", brazeGUID, false); @@ -114,26 +127,16 @@ private static void ModifyProject(string path) { /// Adds the Push entitlement to the host Unity iOS application private static void AddPushEntitlement(string path, PBXProject project, string target) { - var entitlements = new PlistDocument(); - - string entitlementsFilename = MainTargetName + ".entitlements"; - string entitlementsRelativePath = MainTargetName + "/" + entitlementsFilename; - string entitlementsPath = path + "/" + entitlementsRelativePath; - - if (File.Exists(entitlementsPath)) { - entitlements.ReadFromFile(entitlementsPath); - } - - if (entitlements.root["aps-environment"] != null) { - return; - } else { - entitlements.root.SetString("aps-environment", "development"); + var entitlementsFilePath = AppboyConfig.IOSEntitlementsFilePath; + if (string.IsNullOrEmpty(entitlementsFilePath)) { + entitlementsFilePath = MainTargetName + ".entitlements"; } + var projectCapabilityManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(path), entitlementsFilePath, null, target); + projectCapabilityManager.AddPushNotifications(true); + projectCapabilityManager.WriteToFile(); - project.AddFile(entitlementsRelativePath, entitlementsFilename); - entitlements.WriteToFile(entitlementsPath); - - project.AddBuildProperty(target, "CODE_SIGN_ENTITLEMENTS", entitlementsRelativePath); + project.AddFile(entitlementsFilePath, Path.GetFileName(entitlementsFilePath)); + project.AddBuildProperty(target, "CODE_SIGN_ENTITLEMENTS", entitlementsFilePath); } /// Based on the properties set in `BrazeConfiguration` in the Unity UI, inserts relevant values @@ -209,6 +212,9 @@ private static void ModifyPlist(string plistPath) { brazeUnityDict.SetBoolean(BRZUnityHandleInAppMessageDisplayKey, AppboyConfig.IOSDisplayInAppMessages); } + // - Set in-app message initial operation + brazeUnityDict.SetInteger(BRZUnityInAppMessageInitialOperation, AppboyConfig.IOSInitialInAppMessageOperation); + // - Set feed listener if (ValidateListenerFields(BRZUnityFeedGameObjectKey, AppboyConfig.IOSFeedGameObjectName, BRZUnityFeedCallbackKey, AppboyConfig.IOSFeedCallbackMethodName)) { diff --git a/Assets/Plugins/Appboy/Editor/PreBuild.cs b/Assets/Plugins/Appboy/Editor/PreBuild.cs index 498a3208..6ae35434 100644 --- a/Assets/Plugins/Appboy/Editor/PreBuild.cs +++ b/Assets/Plugins/Appboy/Editor/PreBuild.cs @@ -70,7 +70,7 @@ private static string GenerateConfigFile() { cfg = AddBooleanKey(cfg, "com_braze_inapp_auto_set_manager_listener_key", AppboyConfig.AndroidSetInAppMessageManagerListenerAutomatically); string displayOperation = "DISPLAY_NOW"; - // Corresponds to `ANDROID_IAM_OPERATIONS` in the config editor. + // Corresponds to `IAM_OPERATIONS` in the config editor. switch (AppboyConfig.AndroidInitialInAppMessageOperation) { case 0: displayOperation = "DISPLAY_NOW"; diff --git a/Assets/Plugins/CHANGELOG.md b/Assets/Plugins/CHANGELOG.md index 4d3a0997..f5d2ee71 100644 --- a/Assets/Plugins/CHANGELOG.md +++ b/Assets/Plugins/CHANGELOG.md @@ -1,3 +1,18 @@ +⚠️ In version 4.0.0, we changed the iOS bridge from AppboyKit, which is written in Objective-C, to the new [Swift SDK](https://github.com/braze-inc/braze-swift-sdk). If you are upgrading from a version below 4.0.0 to a version above 4.0.0, please read [the instructions](https://github.com/braze-inc/braze-unity-sdk/blob/master/CHANGELOG.md#400) to ensure a smooth transition and backward compatibility. + +## 6.0.0 + +##### Breaking +- Updated the native iOS bridge [from Braze Swift SDK 7.7.0 to 9.0.0](https://github.com/braze-inc/braze-swift-sdk/compare/7.7.0...9.0.0#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed). +- Updated the native Android bridge [from Braze Android SDK 29.0.1 to 30.3.0](https://github.com/braze-inc/braze-android-sdk/compare/v29.0.1...v30.3.0#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed). + +##### Added +- Added iOS _In App Message Manager Initial Display Operation_ configuration setting. + - This setting allows you to configure the initial display operation for in-app messages on iOS. For instance, set it to _Display Later_ to delay the initial display of in-app messages until after your game has finished loading, and use the `AppboyBinding.DisplayNextInAppMessage()` method to display it when ready. +- Added the _Entitlements File Path_ configuration setting. + - This setting allows you to specify the path to an entitlements file to be used / modified by Braze in the Xcode project. + - If left blank, the default entitlements file will be used / created. + ## 5.2.1 ##### Fixed @@ -89,6 +104,7 @@ BRZConfiguration *config = [[BRZConfiguration alloc] init]; Braze *braze = [AppboyUnityManager initBraze:config]; ``` + - This migration requires re-identifying users. To do so, you must call the `changeUser` method on the Braze instance for non-anonymous users. You can read more about it [here](https://braze-inc.github.io/braze-swift-sdk/documentation/braze/appboy-migration-guide/#Re-identify-users). - Reference [this Migration Guide](https://braze-inc.github.io/braze-swift-sdk/documentation/braze/appboy-migration-guide) and [this documentation](https://braze-inc.github.io/braze-swift-sdk/documentation/brazekit) for additional context around specific migration / integration steps. - Requires Unity version [2020.3.42](https://unity.com/releases/editor/whats-new/2020.3.42) or newer. - The following changes have been made to `AppboyUnityManager.h`: diff --git a/Assets/Plugins/iOS/AppboyUnityManager.h b/Assets/Plugins/iOS/AppboyUnityManager.h index 41eaf79b..2053518e 100644 --- a/Assets/Plugins/iOS/AppboyUnityManager.h +++ b/Assets/Plugins/iOS/AppboyUnityManager.h @@ -16,6 +16,7 @@ static NSString *const BRZUnityPushOpenedGameObjectKey = @"PushOpenedGameObjectN static NSString *const BRZUnityPushOpenedCallbackKey = @"PushOpenedCallbackMethodName"; static NSString *const BRZUnityInAppMessageGameObjectKey = @"InAppMessageGameObjectName"; static NSString *const BRZUnityInAppMessageCallbackKey = @"InAppMessageCallbackMethodName"; +static NSString *const BRZUnityInAppMessageInitialOperation = @"InAppMessageInitialOperation"; static NSString *const BRZUnityFeedGameObjectKey = @"FeedGameObjectName"; static NSString *const BRZUnityFeedCallbackKey = @"FeedCallbackMethodName"; static NSString *const BRZUnityContentCardsGameObjectKey = @"ContentCardsGameObjectName"; diff --git a/Assets/Plugins/iOS/AppboyUnityManager.mm b/Assets/Plugins/iOS/AppboyUnityManager.mm index 45ed7326..fb047a16 100644 --- a/Assets/Plugins/iOS/AppboyUnityManager.mm +++ b/Assets/Plugins/iOS/AppboyUnityManager.mm @@ -87,7 +87,8 @@ + (Braze *)initBraze:(BRZConfiguration *)configuration { - (instancetype)init { self = [super init]; if (self) { - self.displayAction = BRZInAppMessageUIDisplayChoiceNow; + // Set initial display action + self.displayAction = (BRZInAppMessageUIDisplayChoice)[brazeUnityPlist[BRZUnityInAppMessageInitialOperation] integerValue]; // Set in-app message UI BrazeInAppMessageUI *inAppMessageUI = [[BrazeInAppMessageUI alloc] init]; diff --git a/CHANGELOG.md b/CHANGELOG.md index db9f39cd..f5d2ee71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ ⚠️ In version 4.0.0, we changed the iOS bridge from AppboyKit, which is written in Objective-C, to the new [Swift SDK](https://github.com/braze-inc/braze-swift-sdk). If you are upgrading from a version below 4.0.0 to a version above 4.0.0, please read [the instructions](https://github.com/braze-inc/braze-unity-sdk/blob/master/CHANGELOG.md#400) to ensure a smooth transition and backward compatibility. +## 6.0.0 + +##### Breaking +- Updated the native iOS bridge [from Braze Swift SDK 7.7.0 to 9.0.0](https://github.com/braze-inc/braze-swift-sdk/compare/7.7.0...9.0.0#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed). +- Updated the native Android bridge [from Braze Android SDK 29.0.1 to 30.3.0](https://github.com/braze-inc/braze-android-sdk/compare/v29.0.1...v30.3.0#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed). + +##### Added +- Added iOS _In App Message Manager Initial Display Operation_ configuration setting. + - This setting allows you to configure the initial display operation for in-app messages on iOS. For instance, set it to _Display Later_ to delay the initial display of in-app messages until after your game has finished loading, and use the `AppboyBinding.DisplayNextInAppMessage()` method to display it when ready. +- Added the _Entitlements File Path_ configuration setting. + - This setting allows you to specify the path to an entitlements file to be used / modified by Braze in the Xcode project. + - If left blank, the default entitlements file will be used / created. + ## 5.2.1 ##### Fixed diff --git a/unity-samples/Assets/Plugins/Android/appboy-ui.aar b/unity-samples/Assets/Plugins/Android/appboy-ui.aar index 5a5d6bfc..7a9dc1d7 100644 Binary files a/unity-samples/Assets/Plugins/Android/appboy-ui.aar and b/unity-samples/Assets/Plugins/Android/appboy-ui.aar differ diff --git a/unity-samples/Assets/Plugins/Android/appboy.aar b/unity-samples/Assets/Plugins/Android/appboy.aar index 005d03ba..1cbae860 100644 Binary files a/unity-samples/Assets/Plugins/Android/appboy.aar and b/unity-samples/Assets/Plugins/Android/appboy.aar differ diff --git a/unity-samples/Assets/Resources/AppboyConfig.asset b/unity-samples/Assets/Resources/AppboyConfig.asset index 81e3e568..e4d768cf 100644 --- a/unity-samples/Assets/Resources/AppboyConfig.asset +++ b/unity-samples/Assets/Resources/AppboyConfig.asset @@ -59,6 +59,7 @@ MonoBehaviour: iOSInAppMessageGameObjectName: BrazeCallback iOSInAppMessageCallbackMethodName: InAppMessageReceivedCallback iOSDisplayInAppMessages: 1 + iOSInitialInAppMessageOperation: 0 androidInAppMessageListenerGameObjectName: BrazeCallback androidInAppMessageListenerCallbackMethodName: InAppMessageReceivedCallback androidTriggerActionMinimumTimeSeconds: