import { NativeModules, Platform } from 'react-native' import BranchEvent from './BranchEvent' const { RNBranch } = NativeModules export default async function createBranchUniversalObject(identifier, options = {}) { if (typeof identifier !== 'string') throw new Error('react-native-branch: identifier must be a string') const contentMetadata = options.contentMetadata || {} if (contentMetadata.customMetadata) { for (const key in contentMetadata.customMetadata) { const valueType = typeof contentMetadata.customMetadata[key] if (valueType == 'string') continue console.warn('[Branch] customMetadata values must be strings. Value for property ' + key + ' has type ' + valueType + '.') // TODO: throw? } } const branchUniversalObject = { canonicalIdentifier: identifier, contentMetadata: contentMetadata, ...options } // For the benefit of NSDecimalNumber on iOS. const price = contentMetadata.price === undefined ? undefined : '' + contentMetadata.price branchUniversalObject.contentMetadata.price = price if (options.automaticallyListOnSpotlight !== undefined) { console.info('[Branch] automaticallyListOnSpotlight is deprecated. Please use locallyIndex instead.') } if (options.price !== undefined) { console.info('[Branch] price is deprecated. Please use contentMetadata.price instead.') } if (options.currency !== undefined) { console.info('[Branch] currency is deprecated. Please use contentMetadata.price instead.') } if (options.metadata !== undefined) { console.info('[Branch] metadata is deprecated. Please use contentMetadata.customMetadata instead.') } if (options.contentIndexingMode !== undefined) { console.info('[Branch] contentIndexingMode is deprecated. Please use locallyIndex or publiclyIndex instead.') } const { ident } = await RNBranch.createUniversalObject(branchUniversalObject) return { ident: ident, showShareSheet(shareOptions = {}, linkProperties = {}, controlParams = {}) { shareOptions = { title: options.title || '', text: options.contentDescription || '', ...shareOptions, } linkProperties = { feature: 'share', channel: 'RNApp', ...linkProperties, } return this._tryFunction(RNBranch.showShareSheet, shareOptions, linkProperties, controlParams) }, // deprecated in favor of userCompletedAction(RegisterViewEvent) registerView() { console.info('[Branch] registerView is deprecated. Please use logEvent(BranchEvent.ViewItem) instead.') return this._tryFunction(RNBranch.registerView) }, generateShortUrl(linkProperties = {}, controlParams = {}) { return this._tryFunction(RNBranch.generateShortUrl, linkProperties, controlParams) }, listOnSpotlight() { console.info('[Branch] listOnSpotlight is deprecated. Please use locallyIndex instead.') if (Platform.OS !== 'ios') return Promise.resolve() return this._tryFunction(RNBranch.listOnSpotlight) }, userCompletedAction(event, state = {}) { console.info('[Branch] userCompletedAction is deprecated. Please use logEvent or the BranchEvent class instead.') if (event == RNBranch.REGISTER_VIEW_EVENT) { return this.logEvent(BranchEvent.ViewItem, { customData: state }) } return this._tryFunction(RNBranch.userCompletedActionOnUniversalObject, event, state) }, logEvent(eventName, params = {}) { return new BranchEvent(eventName, this, params).logEvent() }, release() { return RNBranch.releaseUniversalObject(this.ident) }, /** * Used by exception handlers when RNBranch::Error::BUONotFound is caught. */ _newIdent() { return RNBranch.createUniversalObject(branchUniversalObject).then(({ident}) => { this.ident = ident return ident }) }, _tryFunction(func, ...args) { return func(this.ident, ...args).catch((error) => { if (error.code != 'RNBranch::Error::BUONotFound') { throw error } return this._newIdent().then((ident) => { return func(ident, ...args) }) }) } } }