- React Nightly build: 20220309-2009-538636440
- HW: Mac M1 Pro, 32 GB RAM
- OS: Monterey 12.2.1
- Ruby: rbenv with ruby 2.7.4 (If you have trouble installing it, try with RUBY_CFLAGS=“-w” rbenv install 2.7.4)
- Node: v16.14.0
This Run creates a new project with ReactNative and migrates it to the new architecture. Then, it creates a Turbo Module and a Fabric Component and it integrates them with the app.
There are a few commits that, if checked out, are interesting points to start with.
- Initial Project
- Working New Architecture Project
- Project with a Turbo Module
- Project with a Fabric Component
The following is a list of issues found while executing the migration with their resolution or workaround.
- React Native and Hermes incopatibility
- Folly compiler flags
- Components not properly generated -> to check whether this is a real issue)
- RCTImageLoader failure
Steps:
npx react-native init AwesomeApp
cd AwesomeApp
npx react-native start
npx react-native run-ios
Steps:
- Open the
AwesomeApp/package.json
- Update the
react-native
version to20220309-2009-538636440
yarn install
cd ios && pod install
- Fix build error in
AppDelegate.m
by replacing thereturn [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
with thereturn [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
npx react-native start
npx react-native run-ios
Steps:
yarn add react-native-codegen
cd ios && pod install
npx react-native start
npx react-native run-ios
Steps:
- Open the
Podfile
- Change
:hermes_enabled
totrue
cd ios && pod install
- open
AwesomeApp.xcworkspace
cmd+r
-> the app builds but when it runs, it crashes.
The issue is due to a temporary incompatibility between Hermes and ReactNative. The team is working on that. For the moment, follow these steps to work around it:
- Open the
AwesomeApp/node_modules/react-native/scripts/react_native_pods.rb
- Go to line 116 and add the following two lines
elsif ENV['BUILD_FROM_GIT'] == '1' pod 'hermes-engine', :git => "https://github.com/facebook/hermes.git"
brew install cmake ninja
-> these are tools used to build hermesBUILD_FROM_GIT=1 pod install
- Open
AwesomeApp.xcworkspace
cmd+r
Steps:
- Open
AwesomeApp.xcworkspace
- Select the
AwesomeApp
project in the project navigator - Select the
AwesomeApp
project in theProjects
panel - Select the
Build Settings
tab - Search for
CLANG_CXX_LANGUAGE_STANDARD
- Select the
C++17
option cmd+r
Steps:
- Open
AwesomeApp.xcworkspace
- Rename the
AwesomeApp/main.m
toAwesomeApp/main.mm
- Rename the
AwesomeApp/AppDelegate.m
toAwesomeApp/AppDelegate.mm
cmd+r
Note: Doing this from Xcode will also update the Xcodeproject file
Steps:
- Open
AwesomeApp.xcworkspace
- Open
AwesomeApp/AppDelegate.mm
- Add the following imports
#import <reacthermes/HermesExecutorFactory.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTJSIExecutorRuntimeInstaller.h>
- Make the
AppDelegate
conforms toRCTCxxBridgeDelegate
. Add this code before the@implementation AppDelegate
:
@interface AppDelegate () <RCTCxxBridgeDelegate> {
}
@end
- Add a base implementation for the
jsExecutorFactoryForBridge
. This code will be updated later
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
return std::make_unique<facebook::react::HermesExecutorFactory>(facebook::react::RCTJSIExecutorRuntimeInstaller([bridge](facebook::jsi::Runtime &runtime) {
if (!bridge) {
return;
}
})
);
}
cmd+b
-> The build will fail with the error'folly/folly-config.h' file not found
.
Folly
requires some additional compiler flags.
- Select the
AwesomeApp
project in the project navigator - Select the
AwesomeApp
target in theTargets
section - Select the
Build Settings
tab - Search for
Other C++ Flags
- Update the
Debug
configuration with the following line:-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1
- Update the
Release
configuration with the following line:-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1
cmd+b
cmd+r
Steps:
- Open
AwesomeApp.xcworkspace
- Open
AwesomeApp/AppDelegate.mm
- Add the following imports:
#import <ReactCommon/RCTTurboModuleManager.h>
#import <React/CoreModulesPlugins.h>
- Make the AppDelegate conforms to
RCTTurboModuleManagerDelegate
:
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
RCTTurboModuleManager *_turboModuleManager;
}
@end
- Add the implementation for the protocol's methods
#pragma mark RCTTurboModuleManagerDelegate
- (Class)getModuleClassFromName:(const char *)name
{
return RCTCoreModulesClassProvider(name);
}
- (std::shared_ptr<facebook::react::TurboModule>)
getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker {
return nullptr;
}
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
return [moduleClass new];
}
Steps:
- Open
AwesomeApp.xcworkspace
- Open
AwesomeApp/AppDelegate.mm
- Update the
jsExecutorFactoryForBridge:(RCTBridge *)bridge
method body with the following code:
// Add these lines to create a TurboModuleManager
if (RCTTurboModuleEnabled()) {
_turboModuleManager =
[[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:self
jsInvoker:bridge.jsCallInvoker];
// Necessary to allow NativeModules to lookup TurboModules
[bridge setRCTTurboModuleRegistry:_turboModuleManager];
if (!RCTTurboModuleEagerInitEnabled()) {
/**
* Instantiating DevMenu has the side-effect of registering
* shortcuts for CMD + d, CMD + i, and CMD + n via RCTDevMenu.
* Therefore, when TurboModules are enabled, we must manually create this
* NativeModule.
*/
[_turboModuleManager moduleForName:"DevMenu"];
}
}
// Add this line...
__weak __typeof(self) weakSelf = self;
return std::make_unique<facebook::react::HermesExecutorFactory>(
facebook::react::RCTJSIExecutorRuntimeInstaller([weakSelf, bridge](facebook::jsi::Runtime &runtime) {
if (!bridge) {
return;
}
// And add these lines to install the bindings...
__typeof(self) strongSelf = weakSelf;
if (strongSelf) {
facebook::react::RuntimeExecutor syncRuntimeExecutor =
[&](std::function<void(facebook::jsi::Runtime & runtime_)> &&callback) { callback(runtime); };
[strongSelf->_turboModuleManager installJSBindingWithRuntimeExecutor:syncRuntimeExecutor];
}
}));
cmd+r
Steps:
- Open
AwesomeApp.xcworkspace
- Open
AwesomeApp/AppDelegate.mm
- Add the
RCTEnableTurboModule(YES);
as first line of the(BOOL)application:didFinishLaunchingWithOptions:
method cmd+r
The app will run, but RN will fail with the following error:
Native Component 'SafeAreaView' that calls codegenNativeComponent was not code generated at build time.
That's because the SafeAreaView specs are a little different at the moment.
To fix the issue, let's cleanup the App.js
code by removing the SafeAreaView
and the StatusBar
Steps:
- Open
AwesomeApp/Podfile
- Before the
:enable_hermes => true
line, add the following lines::app_path => "#{Dir.pwd}/..",
:fabric_enabled => true,
- Run
BUILD_FROM_GIT=1 RCT_NEW_ARCH_ENABLED=1 pod install
- Open
AwesomeApp.xcworkspace
cmd+r
If you get a RN error about ImageLoader
, you can solve it by:
- Open the
AwesomeApp.xcworkspace
- Open the
AppDelegate.mm
- Before the
#import <ReactCommon/RCTTurboModuleManager.h>
, add the following imports:
#import <React/RCTDataRequestHandler.h>
#import <React/RCTHTTPRequestHandler.h>
#import <React/RCTFileRequestHandler.h>
#import <React/RCTNetworking.h>
#import <React/RCTImageLoader.h>
#import <React/RCTGIFImageDecoder.h>
#import <React/RCTLocalAssetImageLoader.h>
- Update the body of the
getModuleInstanceFromClass
method with the following code:
if (moduleClass == RCTImageLoader.class) {
return [[moduleClass alloc] initWithRedirectDelegate:nil
loadersProvider:^NSArray<id<RCTImageURLLoader>> *(RCTModuleRegistry * moduleRegistry) {
return @ [[RCTLocalAssetImageLoader new]];
}
decodersProvider:^NSArray<id<RCTImageDataDecoder>> *(RCTModuleRegistry * moduleRegistry) {
return @ [[RCTGIFImageDecoder new]];
}];
} else if (moduleClass == RCTNetworking.class) {
return [[moduleClass alloc]
initWithHandlersProvider:^NSArray<id<RCTURLRequestHandler>> *(
RCTModuleRegistry *moduleRegistry) {
return @[
[RCTHTTPRequestHandler new],
[RCTDataRequestHandler new],
[RCTFileRequestHandler new],
];
}];
}
return [moduleClass new];
cmd+r
The error is caused by a module used by the app to load images that requires some custom parameter at init time to work properly.
Steps:
- Open the
AwesomeApp.xcworkspace
- Open the
AppDelegate.mm
- Add the following imports:
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <react/config/ReactNativeConfig.h>
- Add the following properties in the
@interface AppDelegare
block:
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
- Replace the line that starts with
UIView *rootView =
in theapplication:didFinishLaunchingWithOptions:
with the following snippet:
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc]
initWithBridge:bridge
contextContainer:_contextContainer];
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
UIView *rootView =
[[RCTFabricSurfaceHostingProxyRootView alloc] initWithBridge:bridge
moduleName:@"AwesomeApp"
initialProperties:nil];
cmd+b
cmd+r
Steps:
- Open the
babel.config.js
- Add this snippet after the
preset
property:
plugins: [
'@babel/plugin-proposal-class-properties',
'./node_modules/react-native/packages/babel-plugin-codegen'
]
- Run
BUILD_FROM_GIT=1 RCT_NEW_ARCH_ENABLED=1 pod install
Steps:
- Open the
AwesomeApp.xcworkspace
- Create a new group in the
AwesomeApp
and call itCalendarModule
- Create a new header file
RCTCalendarModule.h
and add this code:
// RCTCalendarModule.h
#import <React/RCTBridgeModule.h>
@interface RCTCalendarModule : NSObject <RCTBridgeModule>
@end
- Create a new objective-c file called ``RCTCalendarModule.m` and add this code:
// RCTCalendarModule.m
#import "RCTCalendarModule.h"
#import <React/RCTLog.h>
@implementation RCTCalendarModule
// To export a module named RCTCalendarModule
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)name location:(NSString *)location)
{
RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
}
@end
cmd+b
cmd+r
Steps:
- In the
AwesomeApp/CalendarModule
group, create ajs
folder - Create a
NativeCalendarModule.js
file - Add the following code:
'use strict';
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
import {TurboModuleRegistry} from 'react-native';
export interface Spec extends TurboModule {
+getConstants: () => {||};
+createCalendarEvent(name: string, location: string): void;
}
export default (TurboModuleRegistry.get<Spec>('CalendarModule'): ?Spec);
Steps:
- In the
AwesomeApp/CalendarModule
group, create aCalendarModule.podspec
file - Copy the following code:
folly_version = '2021.06.28.00-v2'
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
Pod::Spec.new do |s|
s.name = "CalendarModule"
s.version = "0.0.1"
s.summary = "Calendar Module"
s.description = "Calendar Module"
s.homepage = "https://github.com/facebook/react-native.git"
s.license = "MIT"
s.platforms = { :ios => "11.0" }
s.author = ""
s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "#{s.version}" }
s.source_files = "./**/*.{h,m,mm,swift}"
s.compiler_flags = folly_compiler_flags
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\""
}
s.dependency "React"
s.dependency "React-RCTFabric" # This is for fabric component
s.dependency "React-Codegen"
s.dependency "RCT-Folly", folly_version
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
end
Steps:
- Open the
package.json
file - At the end of the file, before the las
}
add the following snippet:
,
"codegenConfig": {
"libraries": [
{
"name": "CalendarModule",
"type": "modules",
"jsSrcsDir": "ios/AwesomeApp/CalendarModule/js"
}
]
}
- Generate the code by running
BUILD_FROM_GIT=1 RCT_NEW_ARCH_ENABLED=1 pod install
. If successful, you should see some lines like these:
#...
[Codegen] >>>>> Processing CalendarModule
[Codegen] Generated schema: /var/folders/b7/5gvyd0914t15w42kwy1k_l600000gn/T/CalendarModuleeSio3t/schema.json
[Codegen] Generated artifacts: /path/to/RNNewArchitectureApp/AwesomeApp/ios/build/generated/ios/CalendarModule
#...
cmd+b
cmd+r
Steps:
- Open the
AwesomeApp.xcworkspace
- Rename the
RCTCalendarModule.m
intoRCTCalendarModule.mm
- Right-click the
AwesomeApp
group in Xcode and selectAdd files to "AwesomeApp"
- Select the
build/generated/ios/CalendarModule
folder - Open the
RCTCalendarModule.h
- Replace the import with
#import <CalendarModule/CalendarModule.h>
- Replace the implemented protocol with
NativeCalendarModuleSpec
- Rename the
RCTCalendarModule.m
intoRCTCalendarModule.mm
- Open the
RCTCalendarModule.mm
- Add the following snippet before the
@end
to connect the component with the generated interface
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeCalendarModuleSpecJSI>(params);
}
cmd+b
cmd+r
Steps:
- Replace the content of the
App.js
file with the following:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React from 'react';
import type {Node} from 'react';
import {
SafeAreaView,
StatusBar,
useColorScheme,
Button,
} from 'react-native';
import {
Colors,
} from 'react-native/Libraries/NewAppScreen';
import CalendarModule from './ios/AwesomeApp/CalendarModule/js/NativeCalendarModule';
const App: () => Node = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<Button
title="Click to invoke your native module!"
color="#841584"
onPress={() => {
CalendarModule.createCalendarEvent('foo', 'bar');
}}/>
</SafeAreaView>
);
};
export default App;
- Update the babel config using the right codegen plugin:
'plugins': [
'@babel/plugin-proposal-class-properties',
'./node_modules/babel-plugin-codegen'
]
- Install the plugin with
yarn add babel-plugin-codegen
- Fix the TurboModule spec interface using this code:
export interface Spec extends TurboModule {
createCalendarEvent(name: string, location: string): void;
}
- Run
BUILD_FROM_GIT=1 RCT_NEW_ARCH_ENABLED=1 pod install
- Run
npx react-native start
- Run
npx react-native run-ios
- Open the
AwesomeApp.xcworkspace
- Set a breakpoint on line 11 of the
RCTCalendarModule.mm
file (theRCTLogInfo
line) - Tap on the Button on the screen and observe the app stopping at the breakpoint.
Steps:
- Open the
NativeCalendarModule.js
file. - Replace the
createCalendarEvent
return type toPromise<string>
- Regenerate code gen running
BUILD_FROM_GIT=1 RCT_NEW_ARCH_ENABLED=1 pod install
- Open
AwesomeApp.xcworkspace
- Open the
RCTCalendarModule.mm
- Leverage the compiler warning to generate the proper
createCalendarEvent
signature. - replace the
RCT_EXPORT_METHOD
with the following code:
RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)name
location:(NSString *)location
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
{
// Do something with the calendar
NSString *eventId = [[NSUUID new] UUIDString];
resolve(eventId);
}
cmd+b
- Open the
App.js
file and update it ad it follows:- Add the
import { useState } from 'react';
statement - Add the
Text
imports in thereact-native
set - Before returning the components, add the
const [eventId, setEventId] = useState<string>("");
- Replace the
<Button />
component with the following code
- Add the
<Button
title="Click to invoke your native module!"
color="#841584"
onPress={async () => {
const newId = await CalendarModule.createCalendarEvent('foo', 'bar');
setEventId(newId);
}}/>
<Text style={{marginLeft:10}}>{eventId.length == 0 ? "No Event Created" : eventId}</Text>
npx react-native start
npx react-native run-ios
- Tap on the button and observe the id that changes.
Steps:
- At the same level of the
App.js
file, create aMapView/js
folder - Create a new file
MapViewNativeComponents.js
- Add this code to the file:
// @flow strict-local
import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
import type {HostComponent} from 'react-native';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
type NativeProps = $ReadOnly<{|
...ViewProps,
zoomEnabled: boolean,
|}>;
export default (codegenNativeComponent<NativeProps>(
'MapView',
): HostComponent<NativeProps>);
Steps
- Go to the
MapView
folder - Create a new file
MapView.podspec
- Add the following code:
# folly_version must match the version used in React Native
# See folly_version in react-native/React/FBReactNativeSpec/FBReactNativeSpec.podspec
folly_version = '2021.06.28.00-v2'
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
boost_compiler_flags = '-Wno-documentation'
Pod::Spec.new do |s|
s.name = "MapView"
s.version = "0.0.1"
s.summary = "Map View Component"
s.description = "Map View Component"
s.homepage = "https://github.com/facebook/react-native.git"
s.license = "MIT"
s.platforms = { :ios => "11.0" }
s.author = "Meta, inc."
s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "#{s.version}" }
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags + ' -Wno-nullability-completeness'
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\"",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
}
s.requires_arc = true
s.dependency "React"
s.dependency "React-RCTFabric"
s.dependency "React-Codegen"
s.dependency "RCT-Folly", folly_version
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
s.source_files = "**/*.{h,m,mm,cpp,swift}"
end
- Open the
package.json
file - Update the
codegenConfig
with the following code
,
{
"name": "MapView",
"type": "components",
"jsSrcsDir": "MapView/js"
}
- generate the code running
BUILD_FROM_GIT=1 RCT_NEW_ARCH_ENABLED=1 pod install
If successfull, you should see something like this:
[Codegen] >>>>> Processing MapView
[Codegen] Generated schema: /var/folders/b7/5gvyd0914t15w42kwy1k_l600000gn/T/MapView0PSxcQ/schema.json
[Codegen] Generated artifacts: /Users/cipolleschi/rn-test/RNNewArchitectureApp/AwesomeApp/ios/build/generated/ios/react/renderer/components/MapView
Steps:
- Go to the
MapView
folder - Create a new folder and name it
ios
- Create a new file called
RNTMapManager.mm
- Paste the following code:
#import <MapKit/MapKit.h>
#import <React/RCTViewManager.h>
@interface RNTMapManager : RCTViewManager
@end
@implementation RNTMapManager
RCT_EXPORT_MODULE(MapView)
RCT_EXPORT_VIEW_PROPERTY(zoomEnabled, BOOL)
- (UIView *)view
{
return [[MKMapView alloc] init];
}
@end
Steps:
- Go to the
MapView/ios
folder - Create a new header file
RNTMapView.h
- Copy the following code:
#ifndef RNTMapView_h
#define RNTMapView_h
#import <React/RCTViewComponentView.h>
#import <UIKit/UIKit.h>
@interface RNTMapView : RCTViewComponentView
@end
#endif /* RNTMapView_h */
- Create a new obbjective-c++ file
RNTMapView.mm
- Copy the following code:
#import "RNTMapView.h"
#import <react/renderer/components/MapView/Props.h>
#import <react/renderer/components/MapView/RCTComponentViewHelpers.h>
#import <react/renderer/components/MapView/ComponentDescriptors.h>
#import <MapKit/MapKit.h>
#import "RCTFabricComponentsPlugins.h"
using namespace facebook::react;
@interface RNTMapView () <RCTMapViewViewProtocol>
@end
@implementation RNTMapView {
MKMapView *_view;
}
+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<MapViewComponentDescriptor>();
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const MapViewProps>();
_props = defaultProps;
_view = [[MKMapView alloc] init];
_view.zoomEnabled = defaultProps->zoomEnabled;
self.contentView = _view;
}
return self;
}
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
const auto &oldViewProps = *std::static_pointer_cast<MapViewProps const>(_props);
const auto &newViewProps = *std::static_pointer_cast<MapViewProps const>(props);
if(oldViewProps.zoomEnabled != newViewProps.zoomEnabled) {
_view.zoomEnabled = newViewProps.zoomEnabled;
}
[super updateProps:props oldProps:oldProps];
}
@end
Class<RCTComponentViewProtocol> MapViewCls(void)
{
return RNTMapView.class;
}
- Open the
AwesomeApp/ios/Podfile
- After the two requires, add this line:
install! 'cocoapods', :deterministic_uuids => false
- After the
use_react_native
function, add the following line:pod "MapView", :path => '../MapView'
- Run
BUILD_FROM_GIT=1 RCT_NEW_ARCH_ENABLED=1 pod install
If successful, you should see something like:Analyzing dependencies Downloading dependencies Installing MapView (0.0.1) Generating Pods project
- Open the
AwesomeApp.xcworkspace
- In the
Pods
project, open theDevelopment Pods
group - Search for
MapView
and check that there are theRNTMapManager.mm
, theRNTMapView.h
and theRNTMapView.mm
files - Select
AwesomeApp
in the Project navigator - Select
AwesomeApp
in the Targets - Select the
General
folder - Scroll down until
Frameworks, Libraries, and Embedded Content
- Add the
MapKit.framework
framework cmd+b
Steps:
- Open the
App.js
- Add the following import
import MapView from './MapView/js/MapViewNativeComponent'
- When rendering the component, add the new MapView
return
<MapView zoomEnabled={false} style={{width:'100%', height:'100%'}}/>
- Fix flow errors, if any
npx react-native run-ios
- Observe the MapView on the screen. Try to pinch to see that the zoom is disabled.
- Change the
zoomEnabled
totrue
- Try to pinch to see that the zoom is enabled.