smartlook / cordova-smartlook

Official Smartlook SDK plugin for Cordova Android and iOS.
https://www.smartlook.com
MIT License
9 stars 6 forks source link

Library not loaded: @rpath/SmartlookAnalytics.framework/SmartlookAnalytics #73

Closed kiwikia closed 1 year ago

kiwikia commented 1 year ago

After installing the plugin (cordova plugins below):

"cordova": { "plugins": { "cordova-plugin-android-permissions": {}, "cordova-plugin-device": {}, "com-badrit-base64": {}, "cordova-plugin-ionic-keyboard": {}, "cordova-plugin-file": { "ANDROIDX_WEBKIT_VERSION": "1.4.0" }, "cordova-plugin-enable-multidex": {}, "cordova-plugin-statusbar": {}, "cordova-plugin-media": { "KEEP_AVAUDIOSESSION_ALWAYS_ACTIVE": "NO" }, "cordova-plugin-camera": { "ANDROIDX_CORE_VERSION": "1.6.+" }, "cordova-plugin-ionic-webview": {}, "cordova-plugin-inappbrowser": {}, "cordova-plugin-network-information": {}, "cordova-plugin-file-opener2": {}, "cordova-plugin-splashscreen": {}, "cordova-plugin-tts": {}, "cordova-plugin-bluetooth-audio": {}, "cordova-plugin-audioinput": {}, "cordova-plugin-add-swift-support": {}, "cordova-plugin-smartlook": {} }, "platforms": [ "android", "ios" ], "engines": { "node": "~18.15.0" } }

And building for ios (we are running an ionic project), the framework isn't found and the application crashes with Library not loaded: @rpath/SmartlookAnalytics.framework/SmartlookAnalytics

We tracked the problem down to the framework not being embedded in the project. Setting the embed="true" flag on the framework resolves the issue.

As a workaround, we are running a hook after smartlook installation to resolve it as follows:

const fs = require('fs'); const path = require('path');

const projectRoot = path.resolve(__dirname, '..', '..');
const pluginDir = path.join(projectRoot, 'plugins', 'cordova-plugin-smartlook');
const pluginXMLPath = path.join(pluginDir, 'plugin.xml');

if (fs.existsSync(pluginXMLPath)) {
  try {
    let xmlContent = fs.readFileSync(pluginXMLPath, 'utf-8');
    if (xmlContent.includes('<framework src="src/ios/SmartlookAnalytics.xcframework" custom="true"/>')) {
      xmlContent = xmlContent.replace(
        '<framework src="src/ios/SmartlookAnalytics.xcframework" custom="true"/>',
        '<framework src="src/ios/SmartlookAnalytics.xcframework" custom="true" embed="true"/>',
      );
      fs.writeFileSync(pluginXMLPath, xmlContent, 'utf-8');
      console.log('Successfully updated smartlook plugin.xml file with embed="true" framework flag');
      return;
    }

    if (xmlContent.includes('<framework src="src/ios/SmartlookAnalytics.xcframework" custom="true" embed="true"/>')) {
      console.log('Smartlook plugin.xml file already contains embed="true" framework flag');
      return;
    }
    console.error(
      'Error updating smartlook plugin.xml file: plugin.xml file does not contain SmartlookAnalytics.xcframework framework',
    );
  } catch (e) {
    console.error('Error updating smartlook plugin.xml file: ', e);
  }
} else {
  console.error('Error updating smartlook plugin.xml file: plugin.xml file not found');
}

Question -> Is there a reason the embed flag is not set? How are others getting this to run without manually embedding the framework?

c0mtru1se commented 1 year ago

Thanks for raising the issue! You are right that the framework should be embedded. It is a historical leftover as we used to distribute our native SDK as a static library, instead of a dynamic one, hence there was no need to embed the framework and also it was common that the Cordova's plugins lib got re-compiled to a single static executable to reduce the runtime linking pressure.

I've fixed the plugin declaration in a new version, 2.0.2 so please kindly try it out and let me know. Your workaround should not be needed now.

Just btw, the embed flag can also be set in Xcode, in the Frameworks, Libraries, and Embedded Content section of your app's target.

Thank you!

kiwikia commented 1 year ago

Thanks @c0mtru1se for the quick turn around! I can confirm all working as expected with the latest release =).