In this post I will show you how to install realm as a dependency in a React Native project with custom folders structure without using react-native link command.
What is React Native? It is one of the most successful and loved mobile development framework. It let you build real native mobile application using Javascript. It has been developed by Facebook. Let’s see the definition from the official website:
Build native mobile apps using JavaScript and React. React Native lets you build mobile apps using only JavaScript. It uses the same design as React, letting you compose a rich mobile UI from declarative components. With React Native, you don’t build a “mobile web app”, an “HTML5 app”, or a “hybrid app”. You build a real mobile app that’s indistinguishable from an app built using Objective-C or Java. React Native uses the same fundamental UI building blocks as regular iOS and Android apps. You just put those building blocks together using JavaScript and React.
Cool !!!! Isn’t it? Write an app using Javascript with the same performance of native code. You can also reuse your native component and bridge them to the javascript side.
Most of the time the React Native framework will help you also to manage dependencies inside you project. But sometimes, especially if your project doesn’t follow the standard React Native directories structure you can have some problem when you try to link you external library.
While I was working on an existing native app integrated with React Native that has a custom directories structure for the react-native and native code, I found some problem to add Realm, the famous open source dbms, as a dependency to the project.
In this post I will show you an example of how you can add Realm to your app that has a custom React Native installation. Let’s start !!
To describe the installation process I will use a sample app I created for this post called
ReactNativeRealmManualLink
. You can find it with realm installed in this github repo.
Suppose you have a project like the one I shared above, in which React Native is contained in a subfolder of the iOS project, instead of the other way around in a standard React Native installation.
First, to add realm as a dependency we need to install it through npm with following command.
npm install --save realm
Then we try to link the library to the native code with the standard React Native command.
react-native link realm
But here something strange happens: as you can see from the screenshot below the command fails to link the library. So we need to find another way to install the library.
Usually, if the previous command fails, you have to do the manual linking.
To do it we navigate inside the node_modules
folder, contained in the React Native folder of our project, to found the realm folder.
Inside it you will find an Xcode project named RealmReact
, that you have to drag into our project. After that we have to add a reference to the static library libRealmReact
and compile the project.
Now you would expect that everything works fine but…
What’s happening? The RealmReact
project is expecting the React Native headers in a relative position with respect to its original position. Argh !! We need to find another way…
What can we do? We can start by observing that the RealmReact
project is just a “container project” for:
RealmJS
project, that generates two static libraries libRealmJS.a
and libGCDWebServers.a
RealmReact
RealmAnalytics
So we can try to modify our main project by:
RealmJS
project and the Objective-C++ files/classes as referenceslibRealmJS.a
and libGCDWebServers.a
to our main project and see if everything worksNow we need to add to the Header search path
option of our main project the paths that were set in the RealmReact
project. In this way the RealmJS
project will be able to find some headers it needs. You can find the complete list of the folder that we need to add in the screenshot below.
Now if we try to compile our app we expect that everything works fine but…ERROR !!! The build fails
!!!
It seems like that in order to be able to compile the C++ source code contained in RealmJS
we need to set a recent C++ version in our project setting that supports some new features like auto return type on static function. We can set it to C++ 14 and set the Standard Library to the LLVM one with C++ 11 support.
One final step is to remove the flag -all_load
from the Other linker flag
option of the main project (if you have it). In this way we avoid to load all Objective-C symbols and have the “duplicated symbols” error.
We are now ready to build our app and see if everything works. To do this we create a sample native view controller that has a RCTRootView
.
class ReactNativeRealmController: UIViewController {
override func viewDidLoad() {
let jsCodeLocation = URL(string: "http://localhost:8081/index.bundle?platform=ios")
view = RCTRootView(
bundleURL: jsCodeLocation,
moduleName: "ReactNativeRealmScreen",
initialProperties: nil,
launchOptions: nil
)
}
}
and a sample react component with some realm write/read operations.
const Realm = require('realm');
class ReactNativeRealmScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
realm: null
};
}
componentWillMount() {
Realm.open({
schema: [{name: 'Band', properties: {name: 'string', singer: 'string'}}]
}).then(realm => {
realm.write(() => {
realm.create('Band', {name: 'HIM', singer: 'Ville Valo'});
});
this.setState({ realm });
});
}
render() {
const message = this.state.realm
? 'The singer of HIM band is: ' + this.state.realm.objects('Band').filtered('name = "HIM"')[0].singer
: 'Loading...';
return (
<View style={styles.container}>
<Text>
{message}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#FFFFFF',
}
});
AppRegistry.registerComponent('ReactNativeRealmScreen', () => ReactNativeRealmScreen, false);
We are now ready to build our app and, as expected, everything works fine.
That’s it!! As I told you before you can find the complete example in this github repo.
We are now ready to create our React Native component with realm .
I recently discovered MockK, a mocking library created for Kotlin. Let’s see how it is possible to write modern unit tests with MockK + JUnit 5.
Read MoreDuring the last months I worked a lot with Spring Boot backend applications. In this post I explain how you can consume a REST api from a Spring Boot application using RestTemplate and (the new) WebClient.
Read MoreRecently I upgraded my ID3TagEditor swift package to the latest Swift tools version (5.3). During the upgraded I discovered that now you can bundle reources with your Swift package. In this post I will show you how you can do this, and also a interesting trick in order to be able to build a project as a Swift Package and as a standard project from Xcode.
Read More