Skip to main content
Version: Next

Turbo Native Modules: iOS

Now it's time to write some iOS platform code to make sure localStorage survives after the application is closed.

Prepare your Xcode Project

We need to prepare your iOS project using Xcode. After completing these 6 steps you'll have RCTNativeLocalStorage that implements the generated NativeLocalStorageSpec interface.

  1. Open the CocoPods generated Xcode Workspace:
cd ios
open TurboModuleExample.xcworkspace
Open Xcode Workspace
  1. Right click on app and select New Group, call the new group NativeLocalStorage.
Right click on app and select New Group
  1. In the NativeLocalStorage group, create NewFile from Template.
Create a new file using the Cocoa Touch Classs template
  1. Use the Cocoa Touch Class.
Use the Cocoa Touch Class template
  1. Name the Cocoa Touch Class RCTNativeLocalStorage with the Objective-C language.
Create an Objective-C RCTNativeLocalStorage class
  1. Rename RCTNativeLocalStorage.mRCTNativeLocalStorage.mm making it an Objective-C++ file.
Convert to and Objective-C++ file

Implement localStorage with NSUserDefaults

Start by updating RCTNativeLocalStorage.h:

NativeLocalStorage/RCTNativeLocalStorage.h
//  RCTNativeLocalStorage.h
// TurboModuleExample

#import <Foundation/Foundation.h>
#import <NativeLocalStorageSpec/NativeLocalStorageSpec.h>

NS_ASSUME_NONNULL_BEGIN

@interface RCTNativeLocalStorage : NSObject
@interface RCTNativeLocalStorage : NSObject <NativeLocalStorageSpec>

@end

Then update our implementation to use NSUserDefaults with a custom suite name.

NativeLocalStorage/RCTNativeLocalStorage.mm
//  RCTNativeLocalStorage.m
// TurboModuleExample

#import "RCTNativeLocalStorage.h"

static NSString *const RCTNativeLocalStorageKey = @"local-stoarge";

@interface RCTNativeLocalStorage()
@property (strong, nonatomic) NSUserDefaults *localStorage;
@end

@implementation RCTNativeLocalStorage

RCT_EXPORT_MODULE(NativeLocalStorage)

- (id) init {
if (self = [super init]) {
_localStorage = [[NSUserDefaults alloc] initWithSuiteName:RCTNativeLocalStorageKey];
}
return self;
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
return std::make_shared<facebook::react::NativeLocalStorageSpecJSI>(params);
}

- (NSString * _Nullable)getItem:(NSString *)key {
return [self.localStorage stringForKey:key];
}

- (void)setItem:(NSString *)value
key:(NSString *)key {
[self.localStorage setObject:value forKey:key];
}

- (void)removeItem:(NSString *)key {
[self.localStorage removeObjectForKey:key];
}

- (void)clear {
NSDictionary *keys = [self.localStorage dictionaryRepresentation];
for (NSString *key in keys) {
[self removeItem:key];
}
}

@end

Important things to note:

  • RCT_EXPORT_MODULE exports and registers the module using the identifier we'll use to access it in the JavaScript environment: NativeLocalStorage. See these docs for more details.
  • You can use Xcode to jump to the Codegen @protocol NativeLocalStorageSpec. You can also use Xcode to generate stubs for you.

Build and run your code on a Simulator

npm run ios