cjam / react-native-spotify-remote

React Native wrapper around the Spotify Remote SDK
MIT License
258 stars 101 forks source link

Undefined symbols for architecture arm64 (Symbol: _OBJC_CLASS_$_SPTConfiguration) #198

Open plasticard opened 2 years ago

plasticard commented 2 years ago

Hi,
I just upgraded to 0.3.11-6 and getting compiler error:

⚠️ ld: ignoring file /Users/expo/workingdir/build/node_modules/react-native-spotify-remote/ios/external/SpotifySDK/SpotifyiOS.framework/SpotifyiOS, file is universal (i386,armv7,x86_64) but does not contain the arm64 architecture: /Users/expo/workingdir/build/node_modules/react-native-spotify-remote/ios/external/SpotifySDK/SpotifyiOS.framework/SpotifyiOS ❌ Undefined symbols for architecture arm64 ┌─ Symbol: _OBJCCLASS$_SPTConfiguration └─ Referenced from: objc-class-ref in libRNSpotifyRemote.a(RNSpotifyRemoteAuth.o)

❌ ld: symbol(s) not found for architecture arm64

❌ clang: error: linker command failed with exit code 1 (use -v to see invocation)

ARCHIVE FAILED

Note: No compiler error with v0.3.10 but having issue with error "Connection attempt failed. Ensure the Spotify app is installed" when trying to connect.

gustavoggs commented 2 years ago

@plasticard can you give more context? It is currently working to me

yzalvov commented 2 years ago

Try adding node_modules/react-native-spotify-remote/ios/external/SpotifySDK/SpotifyiOS.xcframework or SpotifyiOS.framework to the Link Binary With Libraries group for your Xcode project. The first one worked for me on an m1 chip macbook.

Just open up your-app.xcworkspace project file in Xcode and check the screenshot for details.

Untitled

adomoshe commented 2 years ago

I don't see the SpotifyiOS.xcframework in here for some reason. Any suggestions?

Screen Shot 2022-08-22 at 10 40 40 PM
yzalvov commented 2 years ago

@adomoshe make sure you're using the latest version of the lib.

Also have you tried the SpotifyiOS.framework (no x in the extension name) instead?

If no success then go ahead and download the Spotify iOS SDK zip from the official GitHub repo and use the .xframework file from there.

adomoshe commented 2 years ago

@yzalvov Thanks! Also have you tried the SpotifyiOS.framework (no x in the extension name) instead? didn't work but If no success then go ahead and download the Spotify iOS SDK zip from the official GitHub repo and use the .xframework file from there. worked perfectly after cleaning build and resetting npm cache

adomoshe commented 2 years ago

Worked great on the simulator but building on device yielded this error. Any ideas?

Screen Shot 2022-08-23 at 9 39 06 PM
adomoshe commented 2 years ago

dyld[14952]: Library not loaded: '@rpath/SpotifyiOS.framework/SpotifyiOS' Referenced from: '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Queue' Reason: tried: '/usr/lib/swift/SpotifyiOS.framework/SpotifyiOS' (no such file), '/usr/lib/swift/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/usr/lib/swift/SpotifyiOS.framework/SpotifyiOS' (no such file), '/usr/lib/swift/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/System/Library/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file) Library not loaded: '@rpath/SpotifyiOS.framework/SpotifyiOS' Referenced from: '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Queue' Reason: tried: '/usr/lib/swift/SpotifyiOS.framework/SpotifyiOS' (no such file), '/usr/lib/swift/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.framework/SpotifyiOS' (no such file), '/usr/lib/swift/SpotifyiOS.framework/SpotifyiOS' (no such file), '/usr/lib/swift/SpotifyiOS.framework/SpotifyiOS' (no such file), '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Frameworks/SpotifyiOS.fr (lldb)

yzalvov commented 2 years ago

@adomoshe I believe you need to use that .xframework from the official Spotify SDK for iOS

jongirard commented 2 years ago

dyld[14952]: Library not loaded: '@rpath/SpotifyiOS.framework/SpotifyiOS' Referenced from: '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Queue'

@yzalvov @adomoshe I'm experiencing this exact issue currently. Xcode 14.1/react-native-spotify-remote latest (1.0.0-1) on intel mac while building to an iPhone. Have tried adding the SpotifyiOS.framework and SpotifyiOS.xcframework from the official Spotify iOS SDK to my app target and including in the "Link Binary With Libraries" group to no avail.

Any suggestions?

yzalvov commented 2 years ago

Hey @jongirard , have you tried cleaning build and resetting npm cache? @adomoshe reported it worked perfectly after that.

jongirard commented 2 years ago

hey @yzalvov thanks, I ended up getting it working. I needed to also go to the "general" tab for the app target and toggle the embed option for SpotifyiOS.xcframework to "Embed & Sign" after which the build/bundle succeeded!

yeniful commented 1 year ago

@jongirard thank you :D

kvbalib commented 1 year ago

I've made a config plugin for Expo managed apps. Maybe someone will find it helpful as it took me some time to crack it, and couldn't find a solution anywhere else. Might need some tweaking to specific project, but basically it worked for me.

index.js

module.exports = require('./withSpotifyRemote')

withSpotifyRemote.js

const withAddedSpotifyRemotePod = require('./ios/withAddedSpotifyRemotePod')
const withAppDelegateMod = require('./ios/withAppDelegateMod')
const withLinkedBinaryToProject = require('./ios/withLinkedBinaryToProject')

exports.default = (config) => {
  // iOS
  config = withAddedSpotifyRemotePod(config)
  config = withAppDelegateMod(config)
  config = withLinkedBinaryToProject(config)

  return config
}

ios/withAddedSpotifyRemotePod.js

const fs = require('fs');
const path = require('path');
const generateCode = require('@expo/config-plugins/build/utils/generateCode');
const configPlugins = require('@expo/config-plugins');

const code = `  pod 'RNSpotifyRemote', :path => '../node_modules/react-native-spotify-remote'`;

/**
 * @typedef {import('@expo/config').ExpoConfig} ExpoConfig
 * @typedef {import('@expo/config').ConfigPlugin} ConfigPlugin
 */

/**
 * Function adds RNSpotifyRemote pod to the project.
 *
 * @param config { ExpoConfig }
 * @returns { ExpoConfig }
 *
 * @type {ConfigPlugin}
 */
const withAddedSpotifyRemotePod = (config) => {
  return configPlugins.withDangerousMod(config, [
    'ios',
    async (config) => {
      const filePath = path.join(
        config.modRequest.platformProjectRoot,
        'Podfile'
      );
      const contents = fs.readFileSync(filePath, 'utf-8');

      const addCode = generateCode.mergeContents({
        tag: 'withAddedSpotifyRemotePod',
        src: contents,
        newSrc: code,
        anchor: /\s*get_default_flags\(\)/i,
        offset: 2,
        comment: '#',
      });

      if (!addCode.didMerge) {
        console.error(
          "ERROR: Cannot add withReactNativeFirebase to the project's ios/Podfile because it's malformed."
        );
        return config;
      }

      fs.writeFileSync(filePath, addCode.contents);

      return config;
    },
  ]);
};

module.exports = withAddedSpotifyRemotePod;

ios/withAppDelegateMod.js

'use strict';
const configPlugins = require('@expo/config-plugins');

/**
 * @typedef {import('@expo/config').ExpoConfig} ExpoConfig
 * @typedef {import('@expo/config').ConfigPlugin} ConfigPlugin
 */

const importString = `#import <RNSpotifyRemote.h>`

const addLinkingString = ` || [RCTLinkingManager application:application openURL:url options:options] || [[RNSpotifyRemoteAuth sharedInstance] application:application openURL:url options:options]`

const addImport = (stringContents) => {
  const importRegex = /^(#import .*)\n/m;

  const match = stringContents.match(importRegex);
  let endOfMatchIndex;
  if (!match || match.index === undefined) {
    // No imports found, just add to start of file:
    endOfMatchIndex = 0;
  } else {
    // Add after first import:
    endOfMatchIndex = match.index + match[0].length;
  }

  stringContents = [
    stringContents.slice(0, endOfMatchIndex),
    importString,
    stringContents.slice(endOfMatchIndex),
  ].join('\n');

  return stringContents;
};

/**
 * Function adds an url handler, in order to support the callback from the Spotify App.
 *
 * @param config { ExpoConfig }
 * @returns { ExpoConfig }
 *
 * @type { ConfigPlugin }
 */
const withAppDelegateMod = (config) => {
  const linkingApiRegex =
    / \|\| \[RCTLinkingManager application:application openURL:url options:options]/;

  return configPlugins.withAppDelegate(config, (config) => {
    let stringContents = config.modResults.contents;

    stringContents = addImport(stringContents);

    stringContents = stringContents.replace(linkingApiRegex, addLinkingString)

    config.modResults.contents = stringContents;

    return config
  })
}

module.exports = withAppDelegateMod

ios/withLinkedBinaryToProject.js

'use strict';
const configPlugins = require('@expo/config-plugins');

/**
 * @typedef {import('@expo/config').ExpoConfig} ExpoConfig
 * @typedef {import('@expo/config').ConfigPlugin} ConfigPlugin
 */

/**
 * Function links SpotifyiOS.xcframework binary with libraries in the project.pbxproj file.
 *
 * @param config { ExpoConfig }
 * @returns { ExpoConfig }
 *
 * @type {ConfigPlugin}
 */
const withLinkedBinaryToProject = (config) => {
  return configPlugins.withXcodeProject((config), async (config) => {
    const basename = 'SpotifyiOS.xcframework'
    const fileRef = '378A9F1929953C0600C87106'
    const frameworksBuildFileId = config.modResults.generateUuid()
    const embedFrameworksBuildFileId = config.modResults.generateUuid()
    const target = config.modResults.getTarget('com.apple.product-type.application')

    /** 1. Link Binary With Libraries **/

    config.modResults.addToPbxBuildFileSection({
      group: 'Frameworks',
      basename,
      uuid: frameworksBuildFileId,
      fileRef,
    })
    config.modResults.addToPbxFileReferenceSection({
      fileRef,
      basename,
      lastKnownFileType: 'wrapper.xcframework',
      name: 'SpotifyiOS.xcframework',
      path: '../node_modules/react-native-spotify-remote/ios/external/SpotifySDK/SpotifyiOS.xcframework',
      sourceTree: '"<group>"',
    })
    config.modResults.addToPbxFrameworksBuildPhase({
      group: 'Frameworks',
      basename,
      uuid: frameworksBuildFileId,
    })
    config.modResults.addToPbxGroup({ basename, fileRef },
      /**
       * PBXGroup 'Frameworks' object key.
       * @type {string}
       */
      Object.keys(config.modResults.hash.project.objects.PBXGroup)[2]
    )

    /** 2. Embed and Sign **/

    config.modResults.addToPbxBuildFileSection({
      group: 'Embed Frameworks',
      basename,
      uuid: embedFrameworksBuildFileId,
      fileRef,
      settings: {
        ATTRIBUTES: ['CodeSignOnCopy', 'RemoveHeadersOnCopy']
      }
    })
    const pbxCopyFilesBuildPhase = config.modResults.addBuildPhase(
      ['../node_modules/react-native-spotify-remote/ios/external/SpotifySDK/SpotifyiOS.xcframework'],
      'PBXCopyFilesBuildPhase',
      'Embed Frameworks',
      target.uuid,
      {},
      ''
    )
    pbxCopyFilesBuildPhase.buildPhase.dstSubfolderSpec = 10

    return config;
  });
}

module.exports = withLinkedBinaryToProject
Pashkagreen commented 1 year ago

dyld[14952]: Library not loaded: '@rpath/SpotifyiOS.framework/SpotifyiOS' Referenced from: '/private/var/containers/Bundle/Application/10A6E331-3D51-433D-8C87-ABB90EC68B95/Queue.app/Queue'

@yzalvov @adomoshe I'm experiencing this exact issue currently. Xcode 14.1/react-native-spotify-remote latest (1.0.0-1) on intel mac while building to an iPhone. Have tried adding the SpotifyiOS.framework and SpotifyiOS.xcframework from the official Spotify iOS SDK to my app target and including in the "Link Binary With Libraries" group to no avail.

Any suggestions?

hey, did you solve the issue installing on iphone?