Featured image of post Hacking a React Native Library: The Easy Way

Hacking a React Native Library: The Easy Way

TLDR:

This post introduces implementing (IOS)Native modules with a real-life scenario. Although not mandatory but skimming through the content of this link will also help you better understand this article. Also, this article is for those who are new to using Native Modules in React Native.

Full working project: GitHub

Back story:

Some days ago I was trying to implement asking user permission for App Tracking Transparency(ATT) (tracking the use in terms of providing relevant ads) on IOS. I was using the react-native-tracking-transparency library but for some reason, it didn’t work. (probably my fault, that library was working on other projects).

So, I’ve decided to look into the source code since it should be a simple implementation according to Apple. Later, I’ve successfully implemented that user permission for ATT using Native modules and copy-pasting the code from that library.

Do You Need This?

When working with third-party libraries, you may find yourself doing some hacking to make that library work in a specific way that you wanted. Understanding the inner working may help you in the future.

Steps:

There are 5 steps:

  1. Create Header file (.h) file.
  2. Create Objective-C (.m) file.
  3. Comparing files between the files in the library and the file we’ve created.
  4. Add strings in info.plist.
  5. Access functions of Objective c (.m) file from App.js.

Step 1: Create Header file ( .h ) file

Make sure your are on the right project

Select New -> File select Header file. Select a template Create the header file
copy-paste the following code to your TrackingTransparency.h (header file).

1
2
3
#import <React/RCTBridgeModule.h>
@interface TrackingTransparency : NSObject <RCTBridgeModule>
@end

Step 2: Create Objective-C (.m) file

Make sure your are on the right project

Select New -> File

Select Objective-C File

Select a template
Give a name.
Create the header file

copy-paste the following code to your TrackingTransparency.m file.

1
2
3
4
#import "TrackingTransparency.h"
@implementation TrackingTransparency
RCT_EXPORT_MODULE();
@end

Step 3: Comparing files between our TrackingTransparency.m with the libraries own TrackingTransparency.m file

Now take a look at the library. We can see that the library contains an “ios” folder and no android folder which means that this library may contain some native code written on swift or objective C.

In that ios folder we can see two files name TrackingTransparency.h and TrackingTransparency.m which are exactly as we have created just now. let’s compare these 2 files to our files.

  1. TrackingTransparency.h on our project and that library are the same. Notice the similarity.

  2. TrackingTransparency.m files are almost the same. But that library contains some extra code: one import statement and 3 functions. We will be using 2 functions among them from React Native side using Native modules. Now we need to copy these extra things to our TrackingTransparency.m file. After copying, our TrackingTransparency.m will look like the following. copied code

  3. Step 4: Add the following lines in our ios/AwesomeProject/Info.plist.

    1
    2
    
    <key>NSUserTrackingUsageDescription</key>
    <string>this line will be shown to the user in the pop up when asking for permission</string>
    

    info.plist Caution: If you don’t add these strings your app may crash.

  4. Now we can easily access the two functions ( requestTrackingPermission() and getTrackingStatus() ) from TrackingTransparency.m using Native Modules. Add the following import statement to your App.js.

1
import NativeModules from 'react-native';

Now we can ask user permission using the following code snippet.

1
NativeModules.TrackingTransparency.requestTrackingPermission()

We can get the current tracking status using the following code snippet.

1
NativeModules.TrackingTransparency.getTrackingStatus()

it will return one of the following string:

  1. denied: The user has denied permission to track.
  2. authorized: The user has given permission to track.
  3. restricted: Authorization to access app-related data that can be used for tracking the user or the device is restricted. source ATTrackingManager.AuthorizationStatus.restricted.
  4. not-determined: Didn’t ask the user to give tracking permission yet. Call requestTrackingPermission().

Side note: if you look at the code here on react-native-tracking-transparency/src/index.ts, you can see almost the same code where Native Modules was used.

Finally, your App.js should look like this full-code

MD. MOHIBUR RAHMAN