Expo SDK v26.0.0 is now available

Expo SDK v26.0.0 is based off the recently released React Native 0.54, “February 2018” and, as you would expect, includes changes from React Native 0.53 “January 2018” as well. The previous SDK release, v25.0.0, was based on React Native 0.52, “December 2017”.

New limitations on the iOS client

Read the full blog post for more information, along with why we had to do this. A quick summary of the impact this may have on your workflows:

  • The Android client will continue with the same functionality as always.
  • The iOS client will no longer be able to open projects published by other Expo users. You will only be able to open projects published by the same account that’s signed in to the Expo client.
  • The QR code scanner and “+” icon (to manually enter a URL) have been removed. Please use exp send with exp, the “Send” button with XDE, or the s hotkey with create-react-native-app to send your project development URL to your phone by SMS or email. We’re working on another solution that will automatically sync open projects to your phone and we’ll be rolling it out shortly (you can try it already in the simulator and on Android).
  • Standalone apps (builds of your project that are submitted to the App Store) will not be impacted in any way by these changes.

Improved iOS standalone app startup time

We recently rebuilt the JavaScript logic around loading your standalone app and wrote it in Objective C instead. When you rebuild your app with exp build:ios you should feel small improvements to startup time compared to the previous version.

Full control over updating apps over-the-air (OTA)

We’ve overhauled much of our OTA updates experience to give developers complete control over when an update is downloaded and applied. We’ve also standardized the default behavior across iOS and Android. If you don’t customize the updates configuration, Expo projects will check for a new release synchronously every time the app is launched, then download and apply it before starting the app if an update is available.

Synchronously updating on startup gives you a nice guarantee: your users will always be using the newest version of your app. But this comes at a cost: app startup time will be significantly slower on poor network connections and when downloading new updates. For consumer apps, we strongly suggest that you consider setting updates.fallbackToCacheTimeout to 0 in app.json in order to always download updates in the background.

Alternatively, you can opt-in to manually control updates by setting updates.checkAutomatically to “ON_ERROR_RECOVERY” in app.json and using the new Expo.Updates module in your code. This allows you to wrap updating in custom logic (e.g. to prompt a user before loading an update, or fetch updates only when the device is on WiFi). You can also now disable OTA updates entirely in standalone or detached apps on both Android and iOS.

Read more in the Updates API documentation.
Related feature request.

Blob support at last!

It took over a year for this pull request to get in good enough shape to land upstream in React Native, and now it’s available in Expo. This resolves a popular feature request. Perhaps the most valuable result of this addition is out-of-the-box support for Firebase Storage (see related forums posts).

Related pull request.
Check out an example project that uploads an image to Firebase Storage.

Drop SDK19, will drop SDK20 next release

We routinely drop SDK versions that have low usage in order to reduce the number of versions that we need to support. This release sees the end of life for SDK 19. As usual, your standalone apps built with SDK 19 will continue to work; however, SDK 19 projects will no longer work within the latest version of the Expo client, and if you need to re-build your standalone app then you’ll need to upgrade from SDK 19, preferably to SDK 26 so you won’t need to update again for a while (and also because each Expo version is better than the last!).

API improvements and additions

GestureHandler has been promoted out of DangerZone

  • You can now import directly from the Expo package:
    import { GestureHandler } from 'expo';.

New Print API in DangerZone

  • An API for iOS (AirPrint) and Android printing functionality.
  • Send remote or local PDFs or HTML strings to be printed by the device printing APIs.

Read the Print API documentation.

New Localization API in DangerZone

  • Supports localized iOS system dialogs in multiple languages for standalone apps created with exp build.
  • Get device country, locale, time zone, and currency codes.

Read the Localization API documentation.

New APIs and performance improvements for GLView

  • GL context now uses OpenGL ES 3.0 to comply with WebGL 2.0 specs.
  • GL & camera integration replaced with another solution that doesn’t need GPUImage (which doesn’t work with OpenGL ES 3.0).
  • GL commands are flushed immediately when blocking commands (e.g. getAttribLocation) have been called.
  • Framebuffers are swapped and then presented on the canvas only when there’s a need to redraw (i.e. when gl.endFrameEXP is called).
  • glViewRef.takeSnapshotAsync() takes a snapshot of the framebuffer and saves it to disk. Read the documentation.

Assorted Calendar fixes

  • Fix Calendar.getCalendarsAsync() crash on some older versions of Android.
  • Added missing constants to Permissions. Related commit.

Assorted A/V and Camera fixes

  • Fixed camera roll permissions in iOS to not return grantedeven when denied. Related issue.
  • Camera now defaults to older Android API, and lets developers force component to use the new (Camera2) API. Related issues.
  • Fixed ImagePicker returning downsized images on Android. Related issue.
  • Fixed flipped video recording on some devices. Related issue.
  • Fixed video player to return isBuffering=true only if playback isn’t likely to keep up. Related issue.
  • Share cookie session with AV player on Android to fix inconsistent Audio.Sound.create behavior. Related issue.
  • Fix issue with ImageManipulator scale on Android.

Assorted improvements to Notifications

  • No longer returns only status=granted when asking for notifications permissions on Android.
  • Fixed issues with local notifications, and Notifications.addListener issues on iOS.
  • More granularity in permissions:
    USER_FACING_NOTIFICATIONS is a new permission, which applies to local, user-facing notifications.
    NOTIFICATIONS is the permission that encompasses user-facing and remote notifications.
    ◦ In the future, REMOTE_NOTIFICATIONS may be a read-only permission (iOS doesn’t let you ask for it directly) that refers to the ability to send remote notifications, regardless of whether they’re user-facing or silent.
    See this related commit.

Other fixes & improvements

  • New projects now all include “assetBundlePatterns”: [ “**/*” ] in app.json by default, which bundles any asset used in your app (via require) in your standalone builds. This is the same default as React Native apps that do not use Expo. Read more about this option.
  • Deprecated the Util module (all methods now implemented in the Localization and Updates modules).
  • Fixed DeviceMotion.stopObserving error on Android. Related issue.
  • Fixed race condition in Location on iOS. Related issue.
  • Make AdMob API consistent with our other APIs. Related commit.
  • Show splash screen on Android when reloading JS — this should make the development experience on Android much more pleasant! Related issue.

Library updates

  • Updated react-native-gesture-handler to 1.0.0-alpha.41.
  • Updated react-native-svg to 6.2.2.
  • Updated react-native-maps to 0.20.1.

Snack Improvements

  • Added support for oEmbed, which enables you to embed Snacks in Medium posts!
  • Made Snacks on Expo user profiles searchable (try it out in the search bar on https://expo.io)
  • Rewrote Snack mobile client from ground up, making module-resolution for Snack consistent with standard React Native and Expo projects and improving stack traces.
  • Improved dependency handling, giving you more control over what’s brought in to your project, and the ability to remove or change the version of your existing imports.
  • Fixed the issue where some large projects containing non-ASCII text would lose some of their code before the project was executed on a device.


Expo SDK

  • Expo.Util is deprecated, functionality has been moved out to Expo.DangerZone.Localization and Expo.Updates.
  • ios.loadJSInBackgroundExperimental is now deprecated, use the new Updates API instead. The equivalent of this configuration is updates.fallbackToCacheTimeout: 0.
  • isRemoteJSEnabled is also deprecated, use updates.enabled instead.

React lifecycle methods

React Native 0.54 depends on React 16.3.0-alpha.1. React 16.3 deprecates the usage of componentWillMount, componentWillReceiveProps, and componentWillUpdate. These have been replaced with static lifecycle methods: getDerivedStateFromProps and getSnapshotBeforeUpdate, but only getDerivedStateFromProps is available in 16.3.0-alpha.1.

Please read this post on the React blog to learn more about the change and why it’ll be valuable for your app in the near future. And if you haven’t seen it yet, do yourself a favor and watch Dan Abramov’s talk about React “Suspense” — it’s incredibly exciting!

You will likely see a lot of warnings in your app both related to your own code and other libraries using these lifecycle methods. Your app will not break, but the warnings will almost certainly be annoying. You can disable the warnings by adding this code to your App.js: console.disableYellowBox = true;. A small price to pay for progress I’d say.

Breaking Changes

  • On iOS, WebBrowser.dismissBrowser() promise now resolves with {type:'dismiss} rather than type:'dismissed'} to match Android
  • AdMob method name changes. requestAd to requestAdAsync, showAd to showAdAsync, isReady to getIsReadyAsync.
  • On iOS, Contacts urls was renamed to urlAddresses to match Android. Related commit.
  • On iOS, calling Notifications.getExpoPushToken() will throw an error if you don’t have permission to send notifications. We recommend call Permissions.getAsync(Permissions.NOTIFICATIONS) and, if needed and you haven’t asked before, Permissions.askAsync(Permissions.NOTIFICATIONS) before getting push token.
  • React native 0.53.0 removed the TextInput autoGrow prop. Commit.

Upgrading Your App

Here’s how to upgrade your app to Expo SDK 26.0.0 from 25.0.0:

  • Close XDE or your exp CLI server
  • In app.json, change sdkVersion to "26.0.0"
  • In package.json, change these dependencies:
    - react-native to "https://github.com/expo/react-native/archive/sdk-26.0.0.tar.gz"
    - expo to "^26.0.0"
    - react to ("16.3.0-alpha.1" — this exact version) 
    - react-navigation to "1.5.8" (if you use it, and be sure to peruse the release notes)
    - jest-expo to "^26.0.0" (if you use it)
    - sentry-expo did not change from "~1.7.0" (if you use it)
  • Delete your project’s node_modules directory and run npm install again (or use Yarn, we love Yarn)
  • Reopen your project in XDE and press “Restart” to clear the packager cache, or run exp start -c if you use use exp.
  • Update the Expo app on your phones from the App Store / Google Play. XDE and exp will automatically update your apps in simulators.
  • If you use ExpoKit: follow the normal ExpoKit upgrade instructions. If you use ExpoKit for iOS, you should follow the additional one-time instructions below.
  • Make sure to check the breaking changes section of this post!

Updating ExpoKit for iOS to SDK 26

  • If your AppDelegate has a line that looks like [_rootViewController loadReactApplication], delete that line.
  • If your Podfile contains a reference to GLog (with capital letters), change it to glog (all lowercase) and re-run pod install.
  • In your Podfile, make sure the ExpoKit dependency includes the GL subspec. (It probably already contains Core and CPP).
  • If your Supporting directory of your Xcode workspace contains files called kernel-manifest.json and kernel.ios.bundle, remove those files.

👋 from (most of) the Expo team