73
loading...
This website collects cookies to deliver better user experience
npx react-native init
.Share with social medias
native popover.RNShare.swift
on ios
folder from our React Native app. We use RN
before module name to indentify that is a Native Module to use on Javascript later.RNShare.swift
, we need to create class object.import Foundation
class RNShare : NSObject {
}
Foundation
on every Swift file in your modulesRNShare.swift
will have our all functions that we need to expose to Javascript related to this module._open
that open the Share window on our app.import Foundation
class RNShare : NSObject {
func _open() -> Void {
let controller = RCTPresentedViewController();
let shareController = UIActivityViewController(activityItems: ["Hello React Native"], applicationActivities: nil);
shareController.popoverPresentationController?.sourceView = controller?.view;
controller?.present(shareController, animated: true, completion: nil)
}
}
UIActivityViewController
, and adding this controller to our React Native view controller (RCTPresentedViewController
) and calling method present
to present on the screen.open
function.import Foundation
class RNShare : NSObject {
func _open(options: NSDictionary) -> Void {
var items = [String]()
let message = RCTConvert.nsString(options["message"])
if message != "" {
items.append(message!)
}
if items.count == 0 {
print("No `message` to share!")
return
}
let controller = RCTPresentedViewController();
let shareController = UIActivityViewController(activityItems: items, applicationActivities: nil);
shareController.popoverPresentationController?.sourceView = controller?.view;
controller?.present(shareController, animated: true, completion: nil)
}
}
options
object, with an object that our message will be passed (or whatever parameter you want).open
was not created with an _
by coincidence. This function is private because we will only call it on Swift object. We need to create another public function that will indicate to call this function on main thread with some extra configs. requiresMainQueueSetup
to manage our queue on main thread.import Foundation
@objc(RNShare)
class RNShare : NSObject {
@objc static func requiresMainQueueSetup() -> Bool {
return false
}
// Reference to use main thread
@objc func open(_ options: NSDictionary) -> Void {
DispatchQueue.main.async {
self._open(options: options)
}
}
func _open(options: NSDictionary) -> Void {
var items = [String]()
let message = RCTConvert.nsString(options["message"])
if message != "" {
items.append(message!)
}
if items.count == 0 {
print("No `message` to share!")
return
}
let controller = RCTPresentedViewController();
let shareController = UIActivityViewController(activityItems: items, applicationActivities: nil);
shareController.popoverPresentationController?.sourceView = controller?.view;
controller?.present(shareController, animated: true, completion: nil)
}
}
@objc
for open
, requiresMainQueueSetup
, and RNShare
. This means that this code will be called on Objective-C and you need this declarations to work as expected.RNShare.m
that will refer to our Swift functions and will expose it to our bridge with Javascript.#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(RNShare, NSObject)
RCT_EXTERN_METHOD(open:(NSDictionary *)options)
@end
NativeModules
from react-native. I like to create a folder called native
on source code and every file is a different native module.import { NativeModules } from 'react-native';
const { RNShare } = NativeModules;
export default RNShare;
import {Button, SafeAreaView} from 'react-native';
import RNShare from './native/RNShare';
const App = () => {
return (
<SafeAreaView style={{ flex: 1 }}>
<Button
title="Share"
onPress={() => RNShare.open({message: 'Bridge with Swift Dev.to Tutorial'})}
/>
</SafeAreaView>
);
};