Adding Facebook frameworks automatically

Using Unity 202.3.18f1, Xcode 15.3, Facebook SDK 16.0.0

I’ve read several topics regarding this issue where six necessary Facebook frameworks are not part of the Frameworks, Libraries and Embedded Content under General in the Unity-iPhone.

Adding the frameworks manually by getting them from “Pods > Pods” works and prevents the app from “crashing” or, more specifically, going into the background and just wanting to stay there on frame 1 of the app’s launch.

I wanted to automatize this however, and two solutions were suggested.

One was to go into the E.D.M., in iOS Resolver, and there, untick the “Link frameworks statically”.
I was weary of doing this did it nevertheless, but it didn’t change anything.

Another solution was to add an attribute in the Dependencies.xml file (Assets/FacebookSDK/Plugins/Editor/Dependencies.xml).
In this case, adding addToAllTargets=“true” to every single of the six iosPod lines within the iosPods block but this didn’t work either.

I even tried combining both but to no avail.

There also were suggestions to fiddle with “Always embed Swift Standard Libraries” in both Unity-iPhone and Unity Frameworks targets, under Build Settings > Build Options, by putting yes in the first target and no to the same option in the second target, but I’m not even sure what these do.

Is the only real solution to run a postprocessingbuild script and force these frameworks to be declared? How would that be done?

I wrote this postprocessor a while back that adds various frameworks and updates the info.plist. Hopefully you can take bits from that to suit your needs: How does Unity Cloud build iOS handle modifications to the Xcode Project?

Oh nice, thank you.
Typically the six frameworks are:

FBSDKCoreKit
FBSDKCoreKit_Basics
FBSDKGamingServicesKit
FBSDKLoginKit
FBSDKShareKit

I note that you use the attribute [PostProcessBuild] without specifying any integer. I already have another script that deals with another issue but it runs with [PostProcessBuild(0)]. Would there be a conflict or anything?
Or I think I’ll just do a mega dump of all the processes into big file and run with it tbh.

I think the number just specifies what order the post processes run in so you might want to make mine (1) if you want it to run last?

This might be useful to look at too, it has an example of embedding the frameworks from a particular directory.

Interesting script. This requires a little modification for the xcframeworks.

The earlier script wasn’t cutting it because it added the six frameworks to the project file but they were not found, and as per the File Inspector, their kind was “missing”, not “unsigned” as they are in the Pods.
If we merely do a “project.AddFrameworkToProject()”, the frameworks will be visible in the Unity-iPhone hierarchy under Frameworks/ in Xcode, but they will not be sort-of declared in Frameworks, Libraries and Embedded Content under General in the Unity-iPhone.
Doing the drag and drop described earlier on to add them to General has them come with the value “embed & sign”, the six of them. That’s what needed to be replicated automatically.

So this other script is three years old and references the .framework, not the .xcframework, which is a folder for Xcode (xc) that contains three ios-arm64 options, each containing a framework.
Since they’re present in the pods, the Target (in this case Unity-iPhone) only needs them added as references in General that point to the xcframeworks in Pods.
AddFileToEmbedFrameworks does embed the xcframeworks, assuming the script localizes them properly from the inside the parallel Pods Project.

EDIT: there seems to be a good solution here.

I also found that the exact same question was asked a year ago but never got answered. Something similar was explored there . I wish the Player settings had a field for that where frameworks or xcframeworked could be declared so they would get embedded as references from the Pods and also set up properly as embed or not, and signed or not.
In fact, why the heck the Facebook SDK for Unity doesn’t come with a iOS-centric script that does it considering how mandatory it is (although it seems that much older versions of the SDK had no such issues).

Hey, sorry my script wasn’t more useful. Hopefully you can find something else that will work for you. I used to do this kind of thing regularly but it’s been quite a long time so my memory is rusty on it. Do the Unity Facebook SDKs not automatically setup the frameworks in a post build script? I’m sure they used to do that kind of thing.

When I worked with pods on the cloud build I made this script ( Adjusting Pods/Pods.xcproject after pod install ) that manually calls ‘pod install’ after the build. From what I remember this auto installs the frameworks in your podfile into the project but I can’t remember whether it actually adds them to the project or just sets up a ‘Frameworks’ folder and then you have to do add them to the project manually (similar to the first script).

(in the above example the podfile is located in Assets/Editor/MyPodfile)

No worries, I did. Using this block did the trick in the script I found earlier on:

        List<string> frameworks = new List<string>
        {
            "FBAEMKit",
            "FBSDKCoreKit",
            "FBSDKCoreKit_Basics",
            "FBSDKGamingServicesKit",
            "FBSDKLoginKit",
            "FBSDKShareKit"
        };

That works. The six frameworks will be embedded as “Embed & Sign”.

There also were requirements to edit the Build Options in the two Targets (Unity-iPhone and UnityFramework), Always Embed Swift Standard Libraries.
In the first Target, the option is set to “No - $(EMBEDDDED_CONTENT_CONTAINS_SWIFT)” while the fix had the user manually set it to “Yes”.
In the second Target, it’s set to “Yes” but the fix needed it to be set to “No”.
I have not observed any crash whatsoever yet despite not editing these values in the post-build process.
Maybe this needs to be covered in the script too, in which case it will need to account for the two different Targets and grab the second one (UnityFramework) by name to set the Build Options adequately.

Manually. The frameworks are definitely added to the podfile (under xcframeworks that contain several variants/cases with the usual frameworks located two steps deeper into the folders, but they’re not accessible through Xcode’s project hierarchy explorer). At least that’s been the case for me and for all the people who complained about it. Many chose to revert to an older SDK but I found that situation very silly. Some even wondered if the support had been abandoned. :slight_smile:

Now I’ll be getting back to the topic of the option I talked about above: ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES

It turns out that the archiving worked but trying to send the file up into heavens proved impossible because of the following issue:

If you encounter this, it is related to the option above and now you would understand why it is necessary to set them properly. Taken from this thread :

The code below summarises how to add Facebook frameworks automatically:

public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuiltProject)  {
            if (buildTarget != BuildTarget.iOS) return;

            var projectPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
            var project = new PBXProject();
            project.ReadFromFile(projectPath);
            var mainTargetGuid = project.GetUnityMainTargetGuid();

            var frameworks = new List<string>
            {
                "FBAEMKit",
                "FBSDKCoreKit",
                "FBSDKCoreKit_Basics",
                "FBSDKGamingServicesKit",
                "FBSDKLoginKit",
                "FBSDKShareKit"
            };
            foreach (var framework in frameworks) {
                var frameworkName = framework + ".xcframework";
                var src = Path.Combine("Pods", framework, "XCFrameworks", frameworkName);
                var frameworkPath = project.AddFile(src, src);
                project.AddFileToBuild(mainTargetGuid, frameworkPath);
                project.AddFileToEmbedFrameworks(mainTargetGuid, frameworkPath);
            }
            // Write.
            project.WriteToFile(projectPath);
        }