Going back and forth between managed and ejected

Hi, as we’re about to submit our managed app to the app stores, I’m worried about some of the IDFA stuff and other things which we don’t need that will balloon permissions and file size.

First, on ejecting, if I don’t explicitly reference things like the FB and Branch APIs, then will those not be brought into the app or do I have to do some explicit work to remove them?

Second, is the following a reasonable workflow?

  1. Eject from the app, and build and submit the minimal standalone app to the app stores
  2. Revert the ejection and continue development in managed mode
  3. When the app needs a new update in the app stores, eject again and submit (including increment version numbers, etc.), and then go back to step 2 and repeat.
1 Like

Here is the process that works for us (obviously depends on which components you’re using):

  1. In app.config.js, increment MAJOR_VERSION_NUMBER (Android always requires that the major version is incremented), and set PATCH_VERSION_NUMBER to the current date.
    1. Note, we have this related code in app.config.js
      const MAJOR_VERSION_NUMBER = 1;
      const MINOR_VERSION_NUMBER = 1;
      const PATCH_VERSION_NUMBER = 20210101;
      const FULL_APP_VERSION = MAJOR_VERSION_NUMBER + "." + MINOR_VERSION_NUMBER + "." + PATCH_VERSION_NUMBER;
      export default {
        [...]
        version: FULL_APP_VERSION,
        ios: {
          buildNumber: FULL_APP_VERSION
        },
        android: {
          versionCode: MAJOR_VERSION_NUMBER
        }
      }
      
  2. Ensure any production-related settings in App.js:
    1. Ensure isDevelopment = false;
    2. Ensure isProduction = true;
    3. Ensure isOffline = false;
  3. git commit -am "Version X.Y.Z: Major changes"
  4. git tag X.Y.Z
  5. git push && git push --tags
  6. Reset the production demo users
    1. This is needed to reset Apple’s demo review user
  7. Make sure you’re logged in to $USER with expo login
  8. expo eject
  9. iOS:
    1. npx pod-install
    2. Open XCode and then open $APP.xcworkspace
    3. Wait for “Indexing” to complete
    4. First time: Preferences } Accounts } Add }
    5. Double click on $APP } Signing & Capabilities } Team: $APP Inc
    6. Update the status bar style:
      1. $APP } $APP } Info.plist
      2. Right Click } Add Row } Status bar style: Light Content
      3. Save the file
    7. If you want to test in emulators, select the emulator type and click Play
    8. Next to the play/stop buttons, to the right of $APP, select Build } Any iOS Device
    9. Product } Archive
    10. Click Distribute App
    11. Wait for an email that “The following build has completed processing”
    12. Quit XCode
    13. There may be a Metro terminal window open. If so, Ctrl+C and then Enter to end it.
    14. Go to App store Connect
      1. Click on $APP
      2. Click on the plus button in the top left to create a new version and put in X.Y.Z
      3. Summarize updates under “What’s New in This Version”
      4. If needed, update screenshots and other metadata.
        1. iPhone 12 Pro Max for 6.5" Screenshots
        2. iPhone 8 Plus for 5.5" Screenshots
        3. iPad Pro (4th Gen) for iPad Pro (3rd Gen) 12.9" Screenshots
        4. iPad Pro (4th Gen) for iPad Pro (2nd Gen) 12.9" Screenshots
      5. Click the button, “Select a build before you submit your app”
        1. Select Yes for encryption and Yes for exemption.
      6. Click Save
      7. Wait for the notification that the app is ready to be tested in Test Flight
      8. Test the app using Test Flight
  10. Android:
    1. Update android/gradle.properties and add to the bottom:
      org.gradle.daemon=true
      org.gradle.configureondemand=true
      org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
      
    2. Update android/app/build.gradle and add to the end of the android section:
          dexOptions {
             javaMaxHeapSize "2g"
          }
      
      1. To disable JS minification in the release build (for improved diagnostics), update project.ext.react:
        project.ext.react = [
            enableHermes: false,
            extraPackagerArgs: [ '--minify=false' ]
        ]
        
    3. Update android/app/src/main/AndroidManifest.xml and replace uses-permission entries with:
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
        <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
        <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
        <uses-permission android:name="android.permission.CAMERA"/>
        <uses-permission android:name="android.permission.RECORD_AUDIO"/>
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.WAKE_LOCK"/>
        <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
      
    4. Update android/build.gradle and add the following right before the end } of the repositories { section of allprojects:
              maven {
                  // expo-camera bundles a custom com.google.android:cameraview
                  url "$rootDir/../node_modules/expo-camera/android/maven"
              }
      
    5. sed -i.bak 's/com.$APP.$NAME.ReactNativeFlipper/com.$APP.ReactNativeFlipper/g' android/app/src/main/java/com/$APP/$NAME/MainApplication.java && rm android/app/src/main/java/com/$APP/$NAME/MainApplication.java.bak
    6. Update android/app/src/main/java/com/$APP/$NAME/MainActivity.java to set the last parameter to true for SplashScreen.show
    7. Update android/app/src/main/res/values/styles.xml to add <item name="android:statusBarColor">@android:color/transparent</item> within the Theme.App.SplashScreen section.
    8. Start Android Studio and wait for initialization to complete
    9. Wait a little bit and it will pop-up “Plugin Update Recommended”; click update and wait for that to finish.
    10. Stop Android Studio
    11. Kill any running gradle daemons
    12. Start Android Studio and wait for initialization to complete
    13. Update the app icon:
      1. Right click on app } New } Image Asset
      2. Foreground Layer } Path: $APP/assets/logowithmarginnobg512.png
      3. Background Layer } Color: fcfcfc
      4. Next
      5. Finish
      6. Do you want to add… } Cancel
    14. Update the notification icon:
      1. Right click on app } New } Image Asset
      2. Icon Type: Notification Icons
      3. Asset Type: Image
      4. Path: $APP/assets/logowithmarginnobg512.png
      5. Name: notification_icon
      6. Trim: Yes
      7. Padding: 0%
      8. Next
      9. Finish
    15. If you want to test in emulators, run the following (or use the later instructions to install the apk):
      1. On Linux:
        1. In one terminal window:
          1. export ANDROID_HOME=$HOME/Android/Sdk/
          2. export PATH=${ANDROID_HOME}/platform-tools/:${PATH}
          3. react-native start
        2. In Android studio, select the emulator type and click Play
        3. Or from another terminal window:
          1. export ANDROID_HOME=$HOME/Android/Sdk/
          2. export PATH=${ANDROID_HOME}/platform-tools/:${PATH}
          3. yarn android
      2. On other operating systems:
        1. In Android studio, select the emulator type and click Play
        2. Or from another terminal window: yarn android
    16. Stop dev server, VS Code, and any other memory intensive programs
    17. Build } Generate Signed Bundle/APK
      1. Android App Bundle
      2. Key store path: files/android/upload-keystore.jks
      3. Key store password: Android Upload Keystore
      4. Key alias: upload
      5. Key password: Android Upload Key
      6. Uncheck “Export encrypted key…”
      7. Next
      8. Delete any previous *.aab and *.apks files under files/android/release/
      9. Destination folder: files/android/
      10. Build Variants: release
      11. Finish
      12. Do you want to add the following file to Git? } Remember, don’t ask again; Cancel
    18. cd files/android/release/
    19. rm *apks
    20. Generate apks: java -jar ../bundletool-all-*.jar build-apks --bundle=app-release.aab --output=app-release.apks --ks=../upload-keystore.jks --ks-key-alias upload
    21. export ANDROID_HOME=$HOME/Android/Sdk/
    22. export PATH=${ANDROID_HOME}/platform-tools/:${PATH}
    23. Connect Android phone by USB and check it’s in adb devices
    24. java -jar ../bundletool-all-*.jar install-apks --apks=app-release.apks
    25. Launch app from phone launcher
    26. Close Android Studio
  11. If the app testing is good:
    1. iOS:
      1. Go to App Store Connect
        1. Click on $APP
        2. Click Submit for Review
    2. Android:
      1. Update the Android app in the Play store:
        1. Go to Google Play Console
        2. Click on $APP
        3. Click on Production
        4. Click Create new release
        5. Upload aab file
        6. Under Release notes, summarize the updates (required)
        <en-US>
        Various bug fixes
        </en-US>
        
        1. Click Save
        2. Click Review Release
        3. Click Start rollout to Production
        4. First time: Configure notifications to email when review is complete: All apps } Settings } Preferences
      2. The store listing (such as screenshots) is updated independently under Store Presence } Main store listing
        1. Pixel 2, Nexus 7, and Nexus 10 used for screenshots
  12. iOS:
    1. git checkout -b X.Y.Z_ios
    2. git add -A .
    3. git commit -am "iOS build"
    4. git push --set-upstream origin X.Y.Z_ios
  13. Android:
    1. git checkout -b X.Y.Z_android
    2. git add -A .
    3. git commit -am "Android build"
    4. git push --set-upstream origin X.Y.Z_android
  14. git checkout master
  15. git clean --force && git reset --hard && rm -rf android/ ios/

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.