Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta: iOS not yet fully functional #21

Closed
rgomezp opened this issue Nov 1, 2021 · 18 comments · Fixed by #36
Closed

Beta: iOS not yet fully functional #21

rgomezp opened this issue Nov 1, 2021 · 18 comments · Fixed by #36
Labels

Comments

@rgomezp
Copy link
Contributor

rgomezp commented Nov 1, 2021

This issue is to highlight that in the beta, the iOS platform is not yet fully functional.

This includes a lack of support for the Notification Service Extension and App Groups, among other issues.

We are working to add support for these very soon. Thanks for your patience.

@rgomezp rgomezp added the Beta label Nov 1, 2021
@rgomezp rgomezp pinned this issue Nov 1, 2021
@pweisensee
Copy link

@rgomezp Now that Expo EAS is out of beta and fully released and free to use, do you have an update on when OneSignal will be usable with this EAS plugin?

We'd like to build our app using EAS and include OneSignal.

@gtokman
Copy link

gtokman commented Nov 23, 2021

@rgomezp Is this related to these errors when running on iOS?

Invariant Violation: Native module cannot be null.
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError
at node_modules/metro-runtime/src/polyfills/require.js:204:6 in guardedLoadModule
at http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:125901:3 in global code

Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError

I followed the README to set up the dependency and add the plugin to my app.config.ts. Initializing OneSignal in the App.tsx causes the error above.

    const appId = Constants?.manifest?.extra?.oneSignalAppId
    OneSignal.setAppId(appId)

@jkasten2
Copy link
Member

jkasten2 commented Nov 24, 2021

@gtokman I don't believe the error is related, I don't see OneSignal listed anywhere in your error message. I also wasn't able to reproduce any build issues with a new expo project with expo run:ios.

I recommending trying to resolve your issue by checking out this answer:
https://stackoverflow.com/a/67292382

@gtokman
Copy link

gtokman commented Nov 25, 2021

@jkasten2, thanks for the help!

Unfortunately, I didn't have any luck with the StackOverflow comments.

Then error only occurred when I tried to initialize OneSignal. If I comment these lines out, the app builds like usual.

... useEffect()
    const appId = Constants?.manifest?.extra?.oneSignalAppId
    OneSignal.setAppId(appId)
...

@Svarto
Copy link

Svarto commented Nov 27, 2021

@rgomezp To add a Target using config plugins, you can use / take inspiration from how I wrote my fully functioning OneSignal config plugin. This is the snippet to add an additional Target:

/*
Function
config = XCodeProject config
targetName: String = name of the new target
iphoneOsTarget: String = iPhone OS to target, incl. decimal point. e.g. "10.0"
devicesTargeted: String = Which devices are targeted (iPhone, iPad or Mac), e.g. "1,2" for iPhone and iPad
 */
function withAddXcodeTarget(
  config,
  targetName,
  iphoneOSTarget,
  devicesTargeted,
  bundleId,
  bundleVersion,
  devTeam
) {
  const appName = config.modRequest.projectName;
  const iosPath = config.modRequest.platformProjectRoot;

  const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
  const extName = targetName;
  const extFiles = [
    "NotificationService.h",
    "NotificationService.m",
    `${extName}-Info.plist`,
    `${extName}.entitlements`,
  ];
  // The directory where the source extension files are stored
  const sourceDir = `./plugins/${extName}/`;

  let proj = xcode.project(projPath);
  proj.parse(function (err) {
    if (err) {
      console.log(`Error parsing iOS project: ${err}`);
    }
    // Copy in the extension files
    fs.mkdirSync(`${iosPath}/${extName}`, { recursive: true });
    extFiles.forEach(function (extFile) {
      let targetFile = `${iosPath}/${extName}/${extFile}`;

      try {
        fs.createReadStream(`${sourceDir}${extFile}`).pipe(
          fs.createWriteStream(targetFile)
        );
      } catch (err) {
        console.log(err);
      }
    });
    // Create new PBXGroup for the extension
    let extGroup = proj.addPbxGroup(extFiles, extName, extName);

    // Add the new PBXGroup to the top level group. This makes the
    // files / folder appear in the file explorer in Xcode.
    let groups = proj.hash.project.objects["PBXGroup"];
    Object.keys(groups).forEach(function (key) {
      if (groups[key].name === undefined) {
        proj.addToPbxGroup(extGroup.uuid, key);
      }
    });

    // Add a target for the extension
    let target = proj.addTarget(extName, "app_extension", extName, bundleId);

    // Add build phases to the new target
    proj.addBuildPhase(
      ["NotificationService.m"],
      "PBXSourcesBuildPhase",
      "Sources",
      target.uuid
    );
    proj.addBuildPhase([], "PBXResourcesBuildPhase", "Resources", target.uuid);
    proj.addBuildPhase(
      [],
      "PBXFrameworksBuildPhase",
      "Frameworks",
      target.uuid
    );

    // Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
    // However, can be more
    let configurations = proj.pbxXCBuildConfigurationSection();
    for (let key in configurations) {
      if (
        typeof configurations[key].buildSettings !== "undefined" &&
        configurations[key].buildSettings.PRODUCT_NAME == `"${extName}"`
      ) {
        let buildSettingsObj = configurations[key].buildSettings;
        buildSettingsObj.DEVELOPMENT_TEAM = devTeam;
        buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = iphoneOSTarget;
        buildSettingsObj.TARGETED_DEVICE_FAMILY = `"${devicesTargeted}"`;
      }
    }

    // Add development teams to both your target and the original project
    proj.addTargetAttribute("DevelopmentTeam", devTeam, target);
    proj.addTargetAttribute("DevelopmentTeam", devTeam);

    fs.writeFileSync(projPath, proj.writeSync());
  });
}```

@rgomezp
Copy link
Contributor Author

rgomezp commented Dec 4, 2021

@Svarto ,
Thanks for your contribution. But unfortunately, we are struggling to get the dependencies linked correctly across targets. There seems to be an unresolved issue in the xcode npm package. The package is a bit tough to work with given they have no documentation or typings.

Were you able to test everything, get notifications as well as things like buttons, badges, etc...?

You can take a look at our progress so far on the nse-support branch.

We would greatly appreciate help from the community, especially anyone deeply familiar with the xcode npm package.

@m1st1ck
Copy link

m1st1ck commented Dec 6, 2021

@gtokman I think I had the same issue when trying to run in expo client on ios (worked fine when eas build). I just wrapped react-native-onesignal, so it switches to mock implementation if onesignal native module is null.

@Svarto
Copy link

Svarto commented Dec 6, 2021

@rgomezp @m1st1ck hmm, not sure what the issue is - with the above helper to add a Target through a config plugin, I get a fully functioning OneSignal integration with EAS. I can build a custom dev client (expo run:ios) and it works.

The challenge with the dependencies not linking is likely covered by the helper function above as it works for me. Would advise to have a look through, as it is a custom written plugin from low level functions from the cordova-xcode package that is not documented anywhere (poor documentation as you mentioned, I learnt the package by reviewing the code on GitHub)

@m1st1ck
Copy link

m1st1ck commented Dec 6, 2021

@Svarto sorry I think I should have be more specific that the error occurs when using Expo Go app from the store. When using custom dev client I don't get the error but, after a quick test now, it seems like I am not getting the user on the onesignal dashboard.

Building a stand alone app with eas build works fine.

@Svarto
Copy link

Svarto commented Dec 6, 2021

@m1st1ck aha, yes 100% the Expo Go app will not work as there are native integrations required for OneSignal which is not present in the Expo Go app.

In development I get them registered in "all users" but it says "simulators are not supported" in the subscription field...

@rgomezp
Copy link
Contributor Author

rgomezp commented Dec 7, 2021

Howdy folks,
@Svarto thanks a lot for your help. We had to make some slight modifications but we are getting close to providing a full functioning NSE on the plugin. The target dependencies weren't being linked (read more in this issue opened by a colleague).

You can take a look on the branch nse-support for the latest progress. Same as you, we had to look at the source code for the xcode library since there is NO documentation and NO typings! We managed to get a full successful build but it seems that even on the dev client (expo run:ios and expo run:android) the native modules are not being loaded (same runtime error as this issue here). However, a colleague of mine had no issues so I believe it could be an expo or react native related bug or environment issue I'm still trying to resolve.

It seems like some folks (including yourself) are also having no issues while others are reporting no users in the dashboard (upon further inspection, this is a result of the native module not loading at all).

If you have any ideas as to why this could be happening, we would appreciate the input.

@m1st1ck , as Svarto mentioned, you will not be able to run on Expo Go since it doesn't come with the native dependencies required by OneSignal. You can think of the config plugin as adding some custom native code to your application. To get those native changes into your build, Expo needs to bundle it into a custom client that includes those changes. Think of it as building your own Expo Go app to run the application. Since the Go app is prebuilt, it will not include any native customizations. That is why it would never work on the Go app.

@rgomezp
Copy link
Contributor Author

rgomezp commented Dec 9, 2021

Please upgrade to 1.0.0-beta8 for the latest changes! Thanks all

@waelabd
Copy link

waelabd commented Dec 10, 2021

Hi,
Thank you for your work.
I have been trying to set up 1.0.0-beta8 but I am still encountering the same previous error :
"Invariant Violation: Your JavaScript code tried to access a native module that doesn't exist in this development client."
Simulator Screen Shot - iPhone 8 - 2021-12-10 at 23 36 59

I have copied and paste the exemple of the OneSignal.ts file, and running initOneSignalClient() in the App.tsx file.

I let you know if I find something.

@jkasten2
Copy link
Member

jkasten2 commented Dec 11, 2021

Issue

@waelabd This plugin requires the react-native-onesignal SDK, and this plugin defines it as a dependency where it is placed in the node_modules. However the root of your specific issue is that react native doesn't seem to link them automatically when it isn't directly in your project.

Work around

To fix this you can run yarn add react-native-onesignal. You may also need to run expo prebuild --clean so your ios and android folders get fully rebuilt so the linking can take effect after you do this.

Fix & Documentation

We will be updating our documentation soon with these details. We are also looking into seeing if we can change this plugin so the extra setup instead required at all.

@waelabd
Copy link

waelabd commented Dec 13, 2021

Thank you @jkasten2 for your answer. It makes sense indeed. I am able to run it locally in the simulator, and it works as expected.

However I have tried to compile it using Expo eas build command and I am running into this error during fastlane compilation :
ld: library not found for -lPods-OneSignalNotificationServiceExtension

Did I miss something again ?

@pilotpirxie
Copy link

Hi @rgomezp. Great to see, you are working on integration with the expo platform! 👏 What's the state of the expo plugin now? If I have a working app with a bare workflow should I migrate to a plugin or would you recommend staying with the current solution?

@rgomezp
Copy link
Contributor Author

rgomezp commented Dec 29, 2021

@waelabd ,
Are you able to reproduce this error manually (i.e. open the xcode workspace and try to build). This might give you some insight.

@pilotpirxie ,
The Expo Plugin is currently in Beta still as we smooth over any potentially remaining issues. But based on feedback and testing, the plugin should be fully functional now across both platforms. We will likely leave the plugin in beta a bit longer to allow for any potential issues to surface.

In terms of whether you should move away from the bare workflow, it is really up to you. The Expo plugin is designed to work even with managed workflows. This is great for integrations that use automated building or testing workflows since it won't necessitate an interruption in order to eject to bare. As EAS continues being built out and more Expo plugins are contributed to the community, I suspect it will be more convenient to remain in the managed workflow to accomplish the bare minimum needed to fully develop, test, and deploy your application.

@jkasten2
Copy link
Member

jkasten2 commented Feb 14, 2022

iOS is now in the same state as Android today. The documentation covers iOS and your app can be built and all the features of OneSignal can be used. Closing and unpinning this issue but feel free to open a new issue if you are still running into any iOS specific issues.

@jkasten2 jkasten2 unpinned this issue Feb 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants