ProjectCapabilityManager.AddInAppPurchase() Not working?

Hi, during works on build automation with PostProcessBuild, I found out that ProjectCapabilityManager.AddInAppPurchase() doesn’t adds In App Purchase capability on XCode project.

Things like AddGameCenter() and AddPushNotifications() works well, but only in-app purchase.

Are there anything I missed or it’s just a bug? I checked out that provisioning profile surely contains In App Purchase feature.

I’m using Unity 2019.4.5f1 with XCode 11.5.

While adding Sign In With Apple capabilities I noticed the ProjectCapabilityManager was not working properly with Unity 2019.4. Basically the moment they divided the whole thing in 2 targets (UnityFrameworkTarget and UnityMainTarget)

What I noticed is that whenever you have an iOS feature that requires to add (1) a Framework and (2) a Capability in the entitlements file you need to:
Add (1) to the UnityFramework target
And (2) to the Main app target.

At least, that’s my experience when trying to add Sign In With Apple programatically on that Unity version.

Sorry for the late reply!

I’ve checked out your answer and tested AddInAppPurchase() on both UnityFramework target and Main app target, but unfortunately it doesn’t work.

Maybe I should wait a while for unity team to patch this issue…

This doesn’t work for me either @garlicdipping101

About Sign in with Apple can use this plugin
Sign in with Apple Unity Plugin

And for Unity 2019.3 or Newer

    private static void ProcessForiOS(string path)
    {
        string projectPath = PBXProject.GetPBXProjectPath(path);
        var project = new PBXProject();
        project.ReadFromString(System.IO.File.ReadAllText(projectPath));

#if UNITY_2019_3_OR_NEWER
        string targetGuid = project.GetUnityMainTargetGuid();
#else
        string targetGuid = project.TargetGuidByName("Unity-iPhone");
#endif
        // In-App Purchase
        project.AddFrameworkToProject(targetGuid, "StoreKit.framework", false);
        System.IO.File.WriteAllText(projectPath, project.WriteToString());

#if UNITY_2019_3_OR_NEWER
        var project = new PBXProject();
        project.ReadFromString(System.IO.File.ReadAllText(projectPath));
        var manager = new ProjectCapabilityManager(projectPath, "Entitlements.entitlements", null, project.GetUnityMainTargetGuid());
        //manager.AddSignInWithAppleWithCompatibility(project.GetUnityFrameworkTargetGuid()); // with Sign in with Apple Unity Plugin
#else
        var manager = new ProjectCapabilityManager(projectPath, "Entitlements.entitlements", PBXProject.GetUnityTargetName());
        //manager.AddSignInWithAppleWithCompatibility(); // with Sign in with Apple Unity Plugin
#endif
        manager.AddInAppPurchase(); // AddFrameworkToProject() With StoreKit.framework
        manager.WriteToFile();
    }
1 Like

May I ask, why do you need In App Purchase capability? Are you using native IAP code? Alternatively, you can use Unity IAP which handles all of this for you.

Hi,

Unity IAP plugin version: 1.23.5.
Build iOS with Unity 2018.4.24f1
The XCode project will auto add In App Purchase capability.

But after my project upgrade to Unity 2019.4.9f1

Build iOS with Unity 2019.4.9f1
The XCode project not auto add In App Purchase capability.

Don’t know why, so I try add In App Purchase capability by code.

I thought if I use any IAP-Related functions, It’s necessary to include iap capability. If Unity IAP handles all for me, then that’s fine - but still, it feels quite a strange behaviour and I’d like to see any warning message or something if I don’t get some result as I expected…

Sorry, it’s expected behavior so no warning message necessary.

Oh… may I ask, If ProjectCapabilityManager.AddInAppPurchase() doesn’t add In-App Purchase capability to project, then what’s its expected behavior??

Maybe I misunderstood something about what ProjectCapabilityManager class really does, but official documentation says ‘This class allows you to add and modify the specifics of Xcode project capabilities’.

So, If I have serious mistake on understanding this class or function, please let me know and it’ll be really helpful.
A more detailed explanation on its expected behavior would also be good.

1 Like

What problem are you trying to solve? Sorry, I don’t know the answer to your question. Does IAP work for you? I’ve built many IAP projects in XCode, and never had to touch that setting.

Does IAP work for you?

Some people might have some custom native code or a different plugin to handle the IAP. The question is not whether they are using Unity’s IAP plugin. The question here is why AddInAppPurchase does NOT add the capability to the project properly.

The answer is ProjectCapabilityManager might not be working properly after Unity splitted the generated Xcode projects in two targets, on Unity 2019.4 (UnityFramework target & Main App target).

If the manager is created with the target returned with GetUnityFrameworkTargetGuid, the required frameworks are added properly, but the capabilities are not added properly

If the manager is created with the target from GetUnityMainTargetGuid, the capabilities are added properly, but the frameworks are not added properly, unless you mark them in the editor configuration tab for one native iOS file (a .m file for example)

I think the way to fix this issue is that Unity’s team fixes the ProjectCapabilityManager to accept BOTH targets, the unity framework, and the main app; and readapts the code inside it so frameworks are added to the UnityFramework target, and capabilities are added to the main app target.

3 Likes

Thanks for your explanation, lupidan. It helped me understand what’s going on a lot!

1 Like

That can work, try it. : )

        /// <summary>
        /// <para>( Replace )</para>
        /// <para>UnityEditor.iOS.Xcode.ProjectCapabilityManager.AddInAppPurchase ()</para>
        /// </summary>
        public void AddInAppPurchase_Replace ()
        {
            var type = typeof ( PBXCapabilityType );
            var flags = BindingFlags.NonPublic | BindingFlags.Instance;
            var types = new [] { typeof ( string ), typeof ( bool ), typeof ( string ), typeof ( bool ) };
            var parameters = new object [] { "com.apple.InAppPurchase", true, "StoreKit.framework", false };
            var pbxCapabilityType = ( PBXCapabilityType ) type.GetConstructor ( flags, null, types, null ).Invoke ( parameters );
            pbxProject.AddCapability ( MainTargetGUID, pbxCapabilityType );
        }

I don’t think you need to add in-app purchase capability manually. however after unity changed the structure,
I’ve found that the in-app purchase capability does not appear in the capabilities unless you add the storekit.framework into the main app target.if you try to add in-app purchase capability manually on xcode you’ll see that the storekit.framework added to the frameworks automatically.so I guess, storekit.framework is connected with capabilities and this is expected behaviour.

1 Like

Thanks, this works for me.

public static void AddInAppPurchase_Replace(BuildTarget buildTarget, string path)
    {
        string projectPath = PBXProject.GetPBXProjectPath(path);
        PBXProject pbxProject = new PBXProject();
        pbxProject.ReadFromString(File.ReadAllText(projectPath));
        string unityTarget = pbxProject.GetUnityFrameworkTargetGuid();
        string mainTarget = pbxProject.GetUnityMainTargetGuid();
        pbxProject.AddFrameworkToProject(unityTarget, "StoreKit.framework", false);
        pbxProject.AddFrameworkToProject(mainTarget, "StoreKit.framework", false);
        pbxProject.WriteToFile(projectPath);
        var entitlementFilePath = "Entitlements.entitlements";
        var manager = new ProjectCapabilityManager(projectPath, entitlementFilePath, null, mainTarget);
        manager.AddInAppPurchase();
        manager.WriteToFile();
    }

“StoreKit.framework” must Add to unityTarget and mainTarget,then AddInAppPurchase can work.

1 Like