diff --git a/example/ios/Podfile b/example/ios/Podfile index 5ae33f0..a73df0c 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -5,7 +5,7 @@ require Pod::Executable.execute_command('node', ['-p', {paths: [process.argv[1]]}, )', __dir__]).strip -platform :ios, min_ios_version_supported +platform :ios, '15.0' prepare_react_native_project! # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index c4a50fe..85af45a 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,4 +1,6 @@ PODS: + - AsyncObjects (2.1.0): + - OrderedCollections (~> 1.0.0) - boost (1.76.0) - CocoaAsyncSocket (7.6.5) - DoubleConversion (1.1.6) @@ -74,10 +76,18 @@ PODS: - hermes-engine/Pre-built (= 0.72.3) - hermes-engine/Pre-built (0.72.3) - libevent (2.1.12) + - MessagePacker (0.4.7) - OpenSSL-Universal (1.1.1100) + - OrderedCollections (1.0.4) - polywrap-react-native (0.1.0): + - PolywrapClient (= 0.0.7) - RCT-Folly (= 2021.07.22.00) - React-Core + - PolywrapClient (0.0.7): + - AsyncObjects (~> 2.1.0) + - MessagePacker (~> 0.4.7) + - PolywrapClientNative (~> 0.0.5) + - PolywrapClientNative (0.0.5) - RCT-Folly (2021.07.22.00): - boost - DoubleConversion @@ -561,6 +571,7 @@ DEPENDENCIES: SPEC REPOS: trunk: + - AsyncObjects - CocoaAsyncSocket - Flipper - Flipper-Boost-iOSX @@ -572,7 +583,11 @@ SPEC REPOS: - FlipperKit - fmt - libevent + - MessagePacker - OpenSSL-Universal + - OrderedCollections + - PolywrapClient + - PolywrapClientNative - SocketRocket - YogaKit @@ -660,6 +675,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: + AsyncObjects: 37d04187100fd9cd545a6570a8ad727c5a3c5090 boost: 57d2868c099736d80fcd648bf211b4431e51a558 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 @@ -677,8 +693,12 @@ SPEC CHECKSUMS: glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 + MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c - polywrap-react-native: 0dcf2da3f35858967a251f9a04c300a7f85b56b2 + OrderedCollections: c754ce5f9e42cf22b73afd73582317347903ab6d + polywrap-react-native: 5c007a8fd4419bfc1fee7ccbddb42b3d0f961304 + PolywrapClient: f1c843780ed739578393651940e23b2e1e288088 + PolywrapClientNative: a1d5df8a4248379095e8abd408b7a4cb9f3fe80c RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: a2faf4bad4e438ca37b2040cb8f7799baa065c18 RCTTypeSafety: cb09f3e4747b6d18331a15eb05271de7441ca0b3 @@ -715,6 +735,6 @@ SPEC CHECKSUMS: Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 44dbf88ce682963cb4adb558aac392e9a3d692de +PODFILE CHECKSUM: 435dd72f65e6f07eddd7f0321c0649abcfaf98bd COCOAPODS: 1.12.1 diff --git a/example/ios/ReactNativeExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/ReactNativeExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/ReactNativeExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/ReactNative-Bridging-Header.h b/ios/PolywrapClientNative-Bridging-Header.h similarity index 100% rename from ios/ReactNative-Bridging-Header.h rename to ios/PolywrapClientNative-Bridging-Header.h diff --git a/ios/PolywrapClientNative.m b/ios/PolywrapClientNative.m new file mode 100644 index 0000000..424e4c8 --- /dev/null +++ b/ios/PolywrapClientNative.m @@ -0,0 +1,21 @@ +#import + +@interface RCT_EXTERN_REMAP_MODULE(PolywrapClient, PolywrapClientNative, NSObject) + +RCT_EXTERN_METHOD(invokeRaw:(NSString *)uri + method:(NSString *)method + args:(NSArray *)args + env:(NSArray *)env + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) + +RCT_EXTERN_METHOD(configureAndBuild:(NSDictionary *)clientConfig + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) + ++ (BOOL)requiresMainQueueSetup +{ + return NO; +} + +@end diff --git a/ios/PolywrapClientNative.swift b/ios/PolywrapClientNative.swift new file mode 100644 index 0000000..7104cdf --- /dev/null +++ b/ios/PolywrapClientNative.swift @@ -0,0 +1,127 @@ +import PolywrapClient +import Foundation + +@objc(PolywrapClientNative) +class PolywrapClientNative: NSObject { + + static func moduleName() -> String! { + return "PolywrapClientNative" + } + + static func requiresMainQueueSetup() -> Bool { + return false + } + + private var client: PolywrapClient? + + @objc(invokeRaw:method:args:env:resolve:reject:) + func invokeRaw( + _ uri: String, + method: String, + args: [UInt8]?, + env: [UInt8]?, + resolve: @escaping RCTPromiseResolveBlock, + reject: @escaping RCTPromiseRejectBlock + ) { + + // Ensure the client is instantiated + if self.client == nil { + let builder = BuilderConfig() + self.client = builder.build() + } + + guard let clientUnwrapped = self.client else { + reject("CLIENT_ERROR", "Failed to initialize client", nil) + return + } + + // Check if the URI is okay + guard let uriSanitized = try? Uri(uri) else { + reject("URI_ERROR", "Uri sanitization failed", nil) + return + } + + // Call client.invokeRaw with the sanitized URI + do { + let result = try clientUnwrapped.invokeRaw( + uri: uriSanitized, + method: method, + args: args, + env: env + ) + resolve(result) + } catch let error as NSError { + reject("INVOKE_ERROR", "Failed to invoke raw method", error) + } + } + + @objc(configureAndBuild:resolve:reject:) + func configureAndBuild( + _ clientConfig: NSDictionary, + resolve: @escaping RCTPromiseResolveBlock, + reject: @escaping RCTPromiseRejectBlock + ) { + do { + var builder = BuilderConfig() + // Handling envs + if let envs = clientConfig["envs"] as? NSDictionary { + for (key, value) in envs { + guard let envName = key as? String, + let envBytes = value as? [UInt8] else { continue } + + guard let uri = try? Uri(envName) else { + reject("CONFIGURE_AND_BUILD_ERROR", "Env uri sanitization failed", nil) + return + } + + builder.ffi.addEnv(uri: uri.ffi, env: envBytes) + } + } + + // Handling interfaces + if let interfaces = clientConfig["interfaces"] as? NSDictionary { + for (key, value) in interfaces { + guard let interfaceName = key as? String, + let implementationsArray = value as? [String] else { continue } + + let implementations = implementationsArray.compactMap { try? Uri($0) } + guard implementations.count == implementationsArray.count else { + reject("IMPLEMENTATION_URI_ERROR", "Implementation uri sanitization failed", nil) + return + } + + guard let interface = try? Uri(interfaceName) else { + reject("CONFIGURE_AND_BUILD_ERROR", "Interface uri sanitization failed", nil) + return + } + builder = builder.addInterfaceImplementations(interface, implementations) + } + } + + // Handling redirects + if let redirects = clientConfig["redirects"] as? NSDictionary { + for (key, value) in redirects { + guard let redirectFrom = key as? String, + let redirectTo = value as? String else { continue } + + + guard let from = try? Uri(redirectFrom) else { + reject("CONFIGURE_AND_BUILD_ERROR", "Redirect from uri sanitization failed", nil) + return + } + + guard let to = try? Uri(redirectTo) else { + reject("CONFIGURE_AND_BUILD_ERROR", "Redirect to uri sanitization failed", nil) + return + } + builder = builder.addRedirect(from, to) + } + } + + self.client = builder.addSystemDefault().build() + resolve(true) + } catch { + reject("CONFIGURE_AND_BUILD_ERROR", "Failed to configure and build client", error) + } + } +} diff --git a/ios/ReactNative.mm b/ios/ReactNative.mm deleted file mode 100644 index 22e9fd7..0000000 --- a/ios/ReactNative.mm +++ /dev/null @@ -1,14 +0,0 @@ -#import - -@interface RCT_EXTERN_MODULE(ReactNative, NSObject) - -RCT_EXTERN_METHOD(multiply:(float)a withB:(float)b - withResolver:(RCTPromiseResolveBlock)resolve - withRejecter:(RCTPromiseRejectBlock)reject) - -+ (BOOL)requiresMainQueueSetup -{ - return NO; -} - -@end diff --git a/ios/ReactNative.swift b/ios/ReactNative.swift deleted file mode 100644 index 3d4a1c8..0000000 --- a/ios/ReactNative.swift +++ /dev/null @@ -1,8 +0,0 @@ -@objc(ReactNative) -class ReactNative: NSObject { - - @objc(multiply:withB:withResolver:withRejecter:) - func multiply(a: Float, b: Float, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void { - resolve(a*b) - } -} diff --git a/ios/ReactNative.xcodeproj/project.pbxproj b/ios/ReactNative.xcodeproj/project.pbxproj index ed4dd08..d837b49 100644 --- a/ios/ReactNative.xcodeproj/project.pbxproj +++ b/ios/ReactNative.xcodeproj/project.pbxproj @@ -7,8 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 5E555C0D2413F4C50049A1A2 /* ReactNative.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* ReactNative.mm */; }; - F4FF95D7245B92E800C19C63 /* ReactNative.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* ReactNative.swift */; }; + F4FF95D7245B92E800C19C63 /* ReactNative.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* ReactNative.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -117,7 +116,6 @@ buildActionMask = 2147483647; files = ( F4FF95D7245B92E800C19C63 /* ReactNative.swift in Sources */, - B3E7B58A1CC2AC0600A0062D /* ReactNative.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -168,7 +166,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.2; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -212,7 +210,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -266,7 +264,7 @@ 58B511EE1A9E6C8500147676 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "ReactNative" */ = { isa = XCConfigurationList; @@ -275,7 +273,7 @@ 58B511F11A9E6C8500147676 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; diff --git a/polywrap-react-native.podspec b/polywrap-react-native.podspec index 0c6f827..fb02c39 100644 --- a/polywrap-react-native.podspec +++ b/polywrap-react-native.podspec @@ -11,10 +11,11 @@ Pod::Spec.new do |s| s.license = package["license"] s.authors = package["author"] - s.platforms = { :ios => "11.0" } + s.platforms = { :ios => "15.0" } s.source = { :git => "https://github.com/polywrap/polywrap-react-native.git", :tag => "#{s.version}" } s.source_files = "ios/**/*.{h,m,mm,swift}" + s.dependency "PolywrapClient", "= 0.0.7" # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.