Giter Site home page Giter Site logo

Comments (20)

xTheEc0 avatar xTheEc0 commented on April 28, 2024 6

Seems like FacebookSDK issue.
FixColdStart() is a 9 year old addition, that now misbehaves.
Maybe in the past it worked, but now Unity trampoline function didFinishLaunchingWithOptions looks completely different, so this ends up editing one function below (isBackgroundLaunchOptions) by accident.

I think the whole regex replacement part can be deleted from FacebookSDK, if anyone wants to make a PR.

As a workaround: In the Xcode build, modify the Unity-iPhone/Classes/UnityAppController.mm isBackgroundLaunchOptions last line from return YES; to return NO;

Bad code:

- (BOOL)isBackgroundLaunchOptions:(NSDictionary*)launchOptions
{
    if (launchOptions.count == 0)
        return NO;

    // launch due to location event, the app likely will stay in background
    BOOL locationLaunch = [[launchOptions valueForKey: UIApplicationLaunchOptionsLocationKey] boolValue];
    if (locationLaunch)
        return YES;
    return YES; // <-- ISSUE HERE
}

Good code:

- (BOOL)isBackgroundLaunchOptions:(NSDictionary*)launchOptions
{
    if (launchOptions.count == 0)
        return NO;

    // launch due to location event, the app likely will stay in background
    BOOL locationLaunch = [[launchOptions valueForKey: UIApplicationLaunchOptionsLocationKey] boolValue];
    if (locationLaunch)
        return YES;
    return NO;
}

P.S It looks like Unity regression (You said 2022.3.12f1 -> 2022.3.13f1), but we just refactored our launch code around there recently, so FBSDK started modifying it randomly, which is the root cause.

from facebook-sdk-for-unity.

Nezz avatar Nezz commented on April 28, 2024 1

@xTheEc0 Was the change in the original code introduced in Unity 2022.3.13 or an earlier version?

from facebook-sdk-for-unity.

PierrePlayrion avatar PierrePlayrion commented on April 28, 2024 1

The crash issue would be fixed with this PR but now deeplink data isn't reaching Unity. This persists in version 2022.3.19f.

from facebook-sdk-for-unity.

PierrePlayrion avatar PierrePlayrion commented on April 28, 2024 1

I managed to overcome the problem by saving the deeplink in objective C and retrieving it later on C# side.
If this can help anyone facing the issue while it's not fixed:

In Unity C# side:

public static class IOSCustomDeepLinkBridge
{
#if !UNITY_EDITOR
        [DllImport("__Internal")]
        private static extern string GetDeeplinkString();
#endif

        public static string RetrieveDeepLinkFromNativeSide()
        {
#if !UNITY_EDITOR
            return GetDeeplinkString();
#else
            return string.Empty;
#endif
        }
}

Added objective C files:
DeeplinkManager.h

#import <Foundation/Foundation.h>

@interface DeeplinkManager : NSObject

+ (instancetype)sharedManager;
- (void)handleDeeplinkURL:(NSURL *)deeplinkURL;
- (void)handleLaunchOptions:(NSDictionary*)launchOptions;
- (NSString *)getDeeplinkString;

@end

DeeplinkManager.mm

#import "DeeplinkManager.h"

extern "C"
{
    char* convertNSStringToCString(const NSString* nsString)
    {
        if (nsString == NULL)
            return NULL;
        
        const char* nsStringUtf8 = [nsString UTF8String];
        //create a null terminated C string on the heap so that our string's memory isn't wiped out right after method's return
        char* cString = (char*) malloc(strlen(nsStringUtf8) + 1);
        strcpy(cString, nsStringUtf8);
        
        return cString;
    }

    const char* GetDeeplinkString() {
        NSString* deeplinkString = [[DeeplinkManager sharedManager] getDeeplinkString];
        return convertNSStringToCString(deeplinkString);
    }
}
    
@interface DeeplinkManager ()

@property (nonatomic, strong) NSString* deeplinkString;

@end

@implementation DeeplinkManager

+ (instancetype) sharedManager {
    static DeeplinkManager* sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

- (void) handleDeeplinkURL:(NSURL*) deeplinkURL {
    // Handle deeplink URL here
    NSLog(@"[DeeplinkManager] Non empty deeplink URL: %@", deeplinkURL);
    
    // Convert URL to string and store it
    self.deeplinkString = [deeplinkURL absoluteString];
}

- (void) handleLaunchOptions:(NSDictionary*) launchOptions {

    NSURL* url = launchOptions[UIApplicationLaunchOptionsURLKey];
    if (url) {
        [self handleDeeplinkURL:url];
    }
}

/**
 * Retrieves the deeplink url stored when the application launched.
 * @return deep link url or empty string if no deeplink.
 */
- (NSString*) getDeeplinkString {
    if (!self.deeplinkString)
    {
        return @"";
    }
    return self.deeplinkString;
}

@end

And finally updating UnityAppController.mm to ensure getting the deeplink data that is not retrieved by Unity when using FBSDK:

 - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
  {
     // rest of the method
    // ...
 
     // Method handleLaunchOption to be called with launchOptions parameter.
     [[DeeplinkManager sharedManager] handleLaunchOption:launchOptions];
 
     // rest of the method, make sure to be called before isBackgroundLaunchOptions check
     if ([self isBackgroundLaunchOptions: launchOptions])
        return YES;
 
     [self initUnityWithApplication: application];
     return NO;
  }

from facebook-sdk-for-unity.

sebastian-dudzic-spl avatar sebastian-dudzic-spl commented on April 28, 2024 1

Few things I have to add:

  • Facebook - I don't understand why it's not fixed yet. It's a big issue and idea to modify not yours code in postprocess is very risky. If you decide to go for it, you need to maintain it...

  • Thanks to all people engaged here, we have a workaround. Thanks a lot guys!

  • If anyone has doubts, full workaround is not breaking deep links logic, all fine.

  • True answer is a bit hidden and I needed to combine code from few replies, so to not cause more people struggle, here it is:

      [PostProcessBuild(10000)]
      public static void IOSBuildPostProcess(BuildTarget target, string pathToBuiltProject)
      {
      .
      .
          FixUniversalLinksColdStartBugInFacebookSDK(pathToBuiltProject);  // Call this function from your IOSBuildPostProcess 
      .
      .
      }
    
      private static void FixUniversalLinksColdStartBugInFacebookSDK(string path)
      {         
    
          string isBackgroundLaunchOptions = @"(?x)(isBackgroundLaunchOptions:\(NSDictionary\*\)launchOptions(?:.*\n)+?\s*return\ )YES(\;\n\})# }";
          string fullPath = Path.Combine(path, Path.Combine("Classes", "UnityAppController.mm"));
          string data = Load(fullPath);
          data = Regex.Replace(
              data,
              isBackgroundLaunchOptions,
              "$1NO$2");
    
          Save(fullPath, data);
          
          static string Load(string fullPath)
          {
              string data;
              FileInfo projectFileInfo = new FileInfo(fullPath);
              StreamReader fs = projectFileInfo.OpenText();
              data = fs.ReadToEnd();
              fs.Close();
    
              return data;
          }
          
          static void Save(string fullPath, string data)
          {
              System.IO.StreamWriter writer = new System.IO.StreamWriter(fullPath, false);
              writer.Write(data);
              writer.Close();
          }
      }
    

from facebook-sdk-for-unity.

david-a-diaz avatar david-a-diaz commented on April 28, 2024 1

In case it helps, in Unity 2022.3.22 (and possibly on other versions) the regex replace is changing both the isBackgroundLaunchOptions method and some of it's uses in the .mm file, to make sure only the method is changed you can use this regex instead:

data = Regex.Replace( data, @"(?x)(\(BOOL\)isBackgroundLaunchOptions.+(?:.*\n)+?\s*return\ )YES(\;\n\})# }", "$1NO$2" );

from facebook-sdk-for-unity.

StrozhDima avatar StrozhDima commented on April 28, 2024

Confirm crashes at startup on SDK versions 15.1.0 and 16.0.2 and Unity 2022.3.16f1
UPD: The problem appeared in version 2022.3.13f. Version 2022.3.12f works without this problem.

from facebook-sdk-for-unity.

Vitalchek avatar Vitalchek commented on April 28, 2024

Great, thank you very much, I spent so much time. Thanks for the answer

from facebook-sdk-for-unity.

StrozhDima avatar StrozhDima commented on April 28, 2024

Unity issue link

from facebook-sdk-for-unity.

mutluerdm avatar mutluerdm commented on April 28, 2024

Thx @xTheEc0

build post process fix :

        [PostProcessBuild(10000)]
        public static void IOSBuildPostProcess(BuildTarget target, string pathToBuiltProject)
        {
        .
        .
            FixColdStartFacebook(pathToBuiltProject);  // Call this function from your IOSBuildPostProcess 
        .
        .
        }


        private const string IsBackgroundLaunchOptions = @"(?x)(isBackgroundLaunchOptions.+(?:.*\n)+?\s*return\ )YES(\;\n\})# }";

        public static void FixColdStartFacebook(string path)
        {
            string fullPath = Path.Combine(path, Path.Combine("Classes", "UnityAppController.mm"));
            string data = Load(fullPath);

            data = Regex.Replace(
                data,
                IsBackgroundLaunchOptions,
                "$1NO$2");

            Save(fullPath, data);
        }
        
        static string Load(string fullPath)
        {
            string data;
            FileInfo projectFileInfo = new FileInfo(fullPath);
            StreamReader fs = projectFileInfo.OpenText();
            data = fs.ReadToEnd();
            fs.Close();

            return data;
        }

        static void Save(string fullPath, string data)
        {
            System.IO.StreamWriter writer = new System.IO.StreamWriter(fullPath, false);
            writer.Write(data);
            writer.Close();
        }

from facebook-sdk-for-unity.

Vitaliy060795 avatar Vitaliy060795 commented on April 28, 2024

I launch Unity successfully from a deep link when I add this code in post process, but Application.absoluteURL is empty (

from facebook-sdk-for-unity.

Vitaliy060795 avatar Vitaliy060795 commented on April 28, 2024

@mutluerdm maybe do you know ? why does it happen ?

from facebook-sdk-for-unity.

Nezz avatar Nezz commented on April 28, 2024

The change in Unity 2022.3.13 that triggered the issue is the following:

iOS: Fixed Unity launching in the background on background location event; fix black screen showing between splash screen and first scene (release build only). (UUM-52515)

Affected versions:
2021.3.31f1
2022.3.11f1
2023.1.17f1
2023.2.0b14
2023.3.0a10

from facebook-sdk-for-unity.

Vitalchek avatar Vitalchek commented on April 28, 2024

@Nezz Is it possible to somehow fix it so that the game starts on unity
2022.3.14f1 version and reads the parameters from the deeplink?

from facebook-sdk-for-unity.

Nezz avatar Nezz commented on April 28, 2024

Yes, see #713

from facebook-sdk-for-unity.

dhess-zynga avatar dhess-zynga commented on April 28, 2024

I also attempted to apply the workaround posted by @mutluerdm, but I saw the same results as @PierrePlayrion (the crash was fixed, but the deeplink was not being handled properly)

To fix that I changed this line:

private const string IsBackgroundLaunchOptions = @"(?x)(isBackgroundLaunchOptions.+(?:.*\n)+?\s*return\ )YES(\;\n\})# }"

... to this:

private const string IsBackgroundLaunchOptions = @"(?x)(isBackgroundLaunchOptions:\(NSDictionary\*\)launchOptions(?:.*\n)+?\s*return\ )YES(\;\n\})# }"

and now my app links are being handled correctly.

(Context: I think the original RegEx changed more than was intended, not only changing the return value of that method, but also where it was called in application:didFinishLaunchingWithOptions)

Unity 2021.3.35f1
Facebook SDK 14.1.0

from facebook-sdk-for-unity.

pgv3n0m avatar pgv3n0m commented on April 28, 2024

I also attempted to apply the workaround posted by @mutluerdm, but I saw the same results as @PierrePlayrion (the crash was fixed, but the deeplink was not being handled properly)

To fix that I changed this line:

private const string IsBackgroundLaunchOptions = @"(?x)(isBackgroundLaunchOptions.+(?:.*\n)+?\s*return\ )YES(\;\n\})# }"

... to this:

private const string IsBackgroundLaunchOptions = @"(?x)(isBackgroundLaunchOptions:\(NSDictionary\*\)launchOptions(?:.*\n)+?\s*return\ )YES(\;\n\})# }"

and now my app links are being handled correctly.

(Context: I think the original RegEx changed more than was intended, not only changing the return value of that method, but also where it was called in application:didFinishLaunchingWithOptions)

Unity 2021.3.35f1 Facebook SDK 14.1.0

with your line change, I get the crash but not with the old one. I am on Unity 2022.3.19f and same FB SDK

Update: Never mind, I had a callback order issue

from facebook-sdk-for-unity.

keitanxkeitan avatar keitanxkeitan commented on April 28, 2024

with your line change, I get the crash but not with the old one. I am on Unity 2022.3.19f and same FB SDK

@pgv3n0m Could you provide the log you get?

from facebook-sdk-for-unity.

pgv3n0m avatar pgv3n0m commented on April 28, 2024

with your line change, I get the crash but not with the old one. I am on Unity 2022.3.19f and same FB SDK

@pgv3n0m Could you provide the log you get?

Nv, seems to work. I had a callback order issue I did in between the testing

from facebook-sdk-for-unity.

gagbaghdas avatar gagbaghdas commented on April 28, 2024

Thanks to @Vitalchek for opening the issue. @sebastian-dudzic-spl and @david-a-diaz for providing the final solution and to all participants for providing your workarounds. ❤️ Community is Power ❤️

from facebook-sdk-for-unity.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.