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

feat: expo config plugin for iOS native code #9

Open
Tracked by #11
castdrian opened this issue Mar 20, 2024 · 5 comments
Open
Tracked by #11

feat: expo config plugin for iOS native code #9

castdrian opened this issue Mar 20, 2024 · 5 comments

Comments

@castdrian
Copy link

it’d be cool if this lib would provide an expo config plugin to perform the native code change in the AppDelegate, since managed projects regenerate the native code when they build

@kesha-antonov
Copy link
Owner

Hi
Nice idea!
If you can please submit PR
I can also check how to do it on the weekend

@castdrian
Copy link
Author

Yeah I'll see to get to it if I have time, it's fairly easy to do thankfully, expo exposes direct apis to inject code into the AppDelegate, this is a nice explanation: https://www.sitepen.com/blog/doing-more-with-expo-using-custom-native-code

@kesha-antonov
Copy link
Owner

Thanks for the hint!

@mtshv
Copy link

mtshv commented Mar 27, 2024

Yo guys,
Sharing my expo config plugin for AppDelegate modification. Works fine so far:

const { withAppDelegate } = require('@expo/config-plugins');

function withRNBackgroundDownloader(expoConfig) {
  return withAppDelegate(expoConfig, async appDelegateConfig => {
    const { modResults: appDelegate } = appDelegateConfig;
    const appDelegateLines = appDelegate.contents.split('\n');

    // Define the code to be added to AppDelegate.mm
    const backgroundDownloaderImport =
      '#import <RNBackgroundDownloader.h> // Required by react-native-background-downloader. Generated by expoPlugins/withRNBackgroundDownloader.js';
    const backgroundDownloaderDelegate = `\n// Delegate method required by react-native-background-downloader. Generated by expoPlugins/withRNBackgroundDownloader.js
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler
{
  [RNBackgroundDownloader setCompletionHandlerWithIdentifier:identifier completionHandler:completionHandler];
}`;

    // Find the index of the AppDelegate import statement
    const importIndex = appDelegateLines.findIndex(line =>
      /^#import "AppDelegate.h"/.test(line),
    );

    // Find the index of the last line before the @end statement
    const endStatementIndex = appDelegateLines.findIndex(line =>
      /@end/.test(line),
    );

    // Insert the import statement if it's not already present
    if (!appDelegate.contents.includes(backgroundDownloaderImport)) {
      appDelegateLines.splice(importIndex + 1, 0, backgroundDownloaderImport);
    }

    // Insert the delegate method above the @end statement
    if (!appDelegate.contents.includes(backgroundDownloaderDelegate)) {
      appDelegateLines.splice(
        endStatementIndex,
        0,
        backgroundDownloaderDelegate,
      );
    }

    // Update the contents of the AppDelegate file
    appDelegate.contents = appDelegateLines.join('\n');

    return appDelegateConfig;
  });
}

module.exports = withRNBackgroundDownloader;

I'd open a PR to add it, but I do not know the appropriate place to put this code 🤷

@castdrian
Copy link
Author

yup that config plugin works like a charm, well done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants