Skip to content

Commit

Permalink
feat: Expose getView() and call it!
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Jan 15, 2025
1 parent 2410f70 commit 1b66e79
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 22 deletions.
31 changes: 21 additions & 10 deletions packages/nitrogen/src/syntax/swift/SwiftHybridObjectBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,26 @@ export function createSwiftHybridObjectCxxBridge(
const name = getHybridObjectName(spec.name)
const moduleName = NitroConfig.getIosModuleName()

const propertiesBridge = spec.properties
.map((p) => getPropertyForwardImplementation(p))
.join('\n\n')
const methodsBridge = spec.methods
.map((m) => getMethodForwardImplementation(m))
.join('\n\n')
const propertiesBridge = spec.properties.map((p) =>
getPropertyForwardImplementation(p)
)

const methodsBridge = spec.methods.map((m) =>
getMethodForwardImplementation(m)
)

const baseClasses = spec.baseTypes.map((base) => {
const baseName = getHybridObjectName(base.name)
return baseName.HybridTSpecCxx
})
const hasBase = baseClasses.length > 0

if (spec.isHybridView && !hasBase) {
methodsBridge.push(
`public final func getView() -> UIView { return __implementation.view }`
)
}

const hybridObject = new HybridObjectType(spec)
const bridgedType = new SwiftCxxBridgedType(hybridObject)
const bridge = bridgedType.getRequiredBridge()
Expand Down Expand Up @@ -88,11 +95,15 @@ public override func getCxxPart() -> bridge.${baseBridge.specializationName} {
}`.trim()
})

const imports = ['import Foundation', 'import NitroModules']
if (spec.isHybridView) {
imports.push('import UIKit')
}

const swiftCxxWrapperCode = `
${createFileMetadataString(`${name.HybridTSpecCxx}.swift`)}
import Foundation
import NitroModules
${imports.join('\n')}
/**
* A class implementation that bridges ${name.HybridTSpec} over to C++.
Expand Down Expand Up @@ -183,10 +194,10 @@ ${hasBase ? `public class ${name.HybridTSpecCxx} : ${baseClasses.join(', ')}` :
}
// Properties
${indent(propertiesBridge, ' ')}
${indent(propertiesBridge.join('\n\n'), ' ')}
// Methods
${indent(methodsBridge, ' ')}
${indent(methodsBridge.join('\n\n'), ' ')}
}
`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@ interface SwiftHybridObjectRegistration {
requiredImports: SourceImport[]
}

export function getHybridObjectConstructorCall(
hybridObjectName: string
): string {
const swiftNamespace = NitroConfig.getIosModuleName()
const autolinkingClassName = `${NitroConfig.getIosModuleName()}Autolinking`
return `${swiftNamespace}::${autolinkingClassName}::create${hybridObjectName}();`
}

export function createSwiftHybridObjectRegistration({
hybridObjectName,
swiftClassName,
}: Props): SwiftHybridObjectRegistration {
const autolinkingClassName = `${NitroConfig.getIosModuleName()}Autolinking`
const swiftNamespace = NitroConfig.getIosModuleName()
const { HybridTSpecCxx, HybridTSpecSwift, HybridTSpec } =
getHybridObjectName(hybridObjectName)

Expand Down Expand Up @@ -55,7 +61,7 @@ public static func create${hybridObjectName}() -> ${bridge.getTypeCode('swift')}
HybridObjectRegistry::registerHybridObjectConstructor(
"${hybridObjectName}",
[]() -> std::shared_ptr<HybridObject> {
${type.getCode('c++')} hybridObject = ${swiftNamespace}::${autolinkingClassName}::create${hybridObjectName}();
${type.getCode('c++')} hybridObject = ${getHybridObjectConstructorCall(hybridObjectName)}
return hybridObject;
}
);
Expand Down
31 changes: 26 additions & 5 deletions packages/nitrogen/src/views/swift/SwiftHybridViewManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,19 @@ import {
} from '../ViewComponentShadowNode.js'
import { createFileMetadataString } from '../../syntax/helpers.js'
import { NitroConfig } from '../../config/NitroConfig.js'
import { getUmbrellaHeaderName } from '../../autolinking/ios/createSwiftUmbrellaHeader.js'
import { getHybridObjectName } from '../../syntax/getHybridObjectName.js'
import { getHybridObjectConstructorCall } from '../../syntax/swift/SwiftHybridObjectRegistration.js'

export function createSwiftHybridViewManager(
spec: HybridObjectSpec
): SourceFile[] {
const cppFiles = createViewComponentShadowNodeFiles(spec)
const namespace = NitroConfig.getCxxNamespace('c++', 'views')
const namespace = NitroConfig.getCxxNamespace('c++')
const swiftNamespace = NitroConfig.getIosModuleName()
const { HybridTSpec, HybridTSpecSwift, HybridTSpecCxx } = getHybridObjectName(
spec.name
)
const { component, descriptorClassName, propsClassName } =
getViewComponentNames(spec)
const autolinking = NitroConfig.getAutolinkedHybridObjects()
Expand All @@ -28,41 +35,55 @@ ${createFileMetadataString(`${component}.mm`)}
#if REACT_NATIVE_VERSION >= 78
#import "${component}.hpp"
#import <memory>
#import <react/renderer/componentregistry/ComponentDescriptorProvider.h>
#import <React/RCTViewComponentView.h>
#import <React/RCTComponentViewFactory.h>
#import <React/UIView+ComponentViewProtocol.h>
#import <UIKit/UIKit.h>
#import "${HybridTSpecSwift}.hpp"
#import "${getUmbrellaHeaderName()}"
using namespace facebook;
using namespace ${namespace};
using namespace ${namespace}::views;
/**
* Represents the React Native View holder for the Nitro "${spec.name}" HybridView.
*/
@interface ${component}: RCTViewComponentView
@end
@implementation ${component}
@implementation ${component} {
std::shared_ptr<${HybridTSpecSwift}> _hybridView;
}
+ (void) load {
[super load];
[RCTComponentViewFactory.currentComponentViewFactory registerComponentViewClass:[${component} class]];
}
+ (react::ComponentDescriptorProvider) componentDescriptorProvider {
return react::concreteComponentDescriptorProvider<${namespace}::${descriptorClassName}>();
return react::concreteComponentDescriptorProvider<${descriptorClassName}>();
}
- (instancetype) init {
if (self = [super init]) {
// TODO: Initialize "${viewImplementation}" view!
std::shared_ptr<${HybridTSpec}> hybridView = ${getHybridObjectConstructorCall(spec.name)}
_hybridView = std::dynamic_pointer_cast<${HybridTSpecSwift}>(hybridView);
}
return self;
}
- (UIView*) contentView {
${swiftNamespace}::${HybridTSpecCxx} swiftPart = _hybridView->getSwiftPart();
return swiftPart.getView();
}
- (void) updateProps:(const react::Props::Shared&)props
oldProps:(const react::Props::Shared&)oldProps {
// TODO: const auto& newViewProps = *std::static_pointer_cast<${namespace}::${propsClassName} const>(props);
// TODO: const auto& newViewProps = *std::static_pointer_cast<${propsClassName} const>(props);
[super updateProps:props oldProps:oldProps];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,55 @@
#if REACT_NATIVE_VERSION >= 78

#import "HybridTestViewComponent.hpp"
#import <memory>
#import <react/renderer/componentregistry/ComponentDescriptorProvider.h>
#import <React/RCTViewComponentView.h>
#import <React/RCTComponentViewFactory.h>
#import <React/UIView+ComponentViewProtocol.h>
#import <UIKit/UIKit.h>

#import "HybridTestViewSpecSwift.hpp"
#import "NitroImage-Swift-Cxx-Umbrella.hpp"

using namespace facebook;
using namespace margelo::nitro::image;
using namespace margelo::nitro::image::views;

/**
* Represents the React Native View holder for the Nitro "TestView" HybridView.
*/
@interface HybridTestViewComponent: RCTViewComponentView
@end

@implementation HybridTestViewComponent
@implementation HybridTestViewComponent {
std::shared_ptr<HybridTestViewSpecSwift> _hybridView;
}

+ (void) load {
[super load];
[RCTComponentViewFactory.currentComponentViewFactory registerComponentViewClass:[HybridTestViewComponent class]];
}

+ (react::ComponentDescriptorProvider) componentDescriptorProvider {
return react::concreteComponentDescriptorProvider<margelo::nitro::image::views::HybridTestViewComponentDescriptor>();
return react::concreteComponentDescriptorProvider<HybridTestViewComponentDescriptor>();
}

- (instancetype) init {
if (self = [super init]) {
// TODO: Initialize "HybridTestView" view!
std::shared_ptr<HybridTestViewSpec> hybridView = NitroImage::NitroImageAutolinking::createTestView();
_hybridView = std::dynamic_pointer_cast<HybridTestViewSpecSwift>(hybridView);
}
return self;
}

- (UIView*) contentView {
NitroImage::HybridTestViewSpec_cxx swiftPart = _hybridView->getSwiftPart();
return swiftPart.getView();
}

- (void) updateProps:(const react::Props::Shared&)props
oldProps:(const react::Props::Shared&)oldProps {
// TODO: const auto& newViewProps = *std::static_pointer_cast<margelo::nitro::image::views::HybridTestViewProps const>(props);
// TODO: const auto& newViewProps = *std::static_pointer_cast<HybridTestViewProps const>(props);

[super updateProps:props oldProps:oldProps];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Foundation
import NitroModules
import UIKit

/**
* A class implementation that bridges HybridTestViewSpec over to C++.
Expand Down Expand Up @@ -139,4 +140,6 @@ public class HybridTestViewSpec_cxx {
return bridge.create_Result_bool_(__exceptionPtr)
}
}

public final func getView() -> UIView { return __implementation.view }
}

0 comments on commit 1b66e79

Please sign in to comment.