使用 NativeScript,我们可以完全访问 Java、Kotlin、Objective-C 和 Swift 中的原生平台 API。所有平台语言都为其带来了独特的结构。使用 Swift,您可以使用所有内容,只要您想要使用的结构将其类型暴露给 Objective-C。
那么,如果 Swift 结构没有暴露给 Objective-C,我们如何将第三方 Swift 代码集成到我们的 NativeScript 应用程序中呢?
这是我们将使用的示例 Swift pod,https://github.com/SwiftKickMobile/SwiftMessages,它允许您以多种方式显示漂亮的邮件卡片。
它也不适用于 Objective-C。
让我们创建一个示例项目
ns create SwiftSample --template @NativeScript/template-hello-world-ts
cd SwiftSample
ns run ios
我们得到了可爱的点击按钮屏幕。
现在我们在我们的应用程序中添加对 pod 的引用
App_Resources/iOS/PodFile
中添加一个文件pod 'SwiftMessages'
此时,我们可以生成类型,这样我们就可以对 Pod 中的内容进行强类型访问。
ns typings ios
这将在 typings/ios/<architecture>
下生成一个文件。
我们确实有一个 objc!SwiftMessages.d.ts
文件,但有一个问题。
如果我查看 SwiftMessages 的文档,一个简单的用例是 SwiftMessages.show(view: myView)
,但我们的类型文件中在哪里没有 SwiftMessages 类?
这里的问题是 SwiftMessages 类没有暴露给 Objective-c,因此无法从 NativeScript 访问。更多信息请访问 这里。
那么解决方案是什么?凭借 NativeScript 的魔力,我们可以
首先,我们在项目中 App_Resources/iOS/src/NSCSwiftMessages.swift
中添加一个新的 Swift 文件。
让我们添加一些代码(从 SwiftMessages github 上的示例复制),以便我们能够从 NativeScript 中调用它。
**注意**:您可以在此处使用任何类前缀,但我们建议使用 NSC
前缀以确保您的类不会与 NS
前缀类冲突,这些类 在整个 iOS 代码中很常见,这是由于 NeXTStep 的整个 iOS 平台的基础。您可以将 NSC
视为“NativeScript”或“NativeScript Compiler”的缩写,如果这能让您更容易记住。这也有助于简化您以这种方式公开的任何平台代码的命名约定,仅供 NativeScript 使用。
import Foundation
import SwiftMessages
@objcMembers
@objc(NSCSwiftMessages)
public class NSCSwiftMessages: NSObject {
// We can assign a callback to this from TypeScript.
@objc public var onDoneCallBack: ((String)-> Void)? = nil;
public func showMessage(title: String, body: String) {
// Instantiate a message view from the provided card view layout. SwiftMessages searches for nib
// files in the main bundle first, so you can easily copy them into your project and make changes.
let view = MessageView.viewFromNib(layout: .cardView)
// Theme message elements with the warning style.
view.configureTheme(.success)
view.button?.isHidden=true;
// Add a drop shadow.
view.configureDropShadow()
view.button?.isHidden=true;
// Set message title, body, and icon. Here, we're overriding the default warning
// image with an emoji character.
let iconText = ["🤔", "😳", "🙄", "😶"].randomElement()!
view.configureContent(title: title, body: body, iconText: iconText)
// Increase the external margin around the card. In general, the effect of this setting
// depends on how the given layout is constrained to the layout margins.
view.layoutMarginAdditions = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
// Reduce the corner radius (applicable to layouts featuring rounded corners).
(view.backgroundView as? CornerRoundingView)?.cornerRadius = 10
var config = SwiftMessages.Config()
// Specify one or more event listeners to respond to show and hide events.
config.eventListeners.append() { event in
if case .didHide = event {
// If the callback is setup call it.
self.onDoneCallBack?("Message Alert Hidden");
}
}
// Show the message.
SwiftMessages.show(config: config, view: view)
}
}
这里重要的元素是我们通过添加注释 @objcMembers
和 @objc
将我们的 swift 暴露给了 Objective-C。
现在,我们可以再次运行类型生成,并将有一个新的文件 objc!nsswiftsupport.d
在这个新文件中,我们将看到我们新类的类型
declare class NSCSwiftMessages extends NSObject {
static alloc(): NSCSwiftMessages; // inherited from NSObject
static new(): NSCSwiftMessages; // inherited from NSObject
onDoneCallBack: (p1: string) => void;
showMessageWithTitleBody(title: string, body: string): void;
}
我们将此文件复制到项目的根目录(或任何有意义的地方),并在 ./references.d.ts
文件中添加对它的引用。
/// <reference path="./node_modules/@nativescript/types/index.d.ts" />
/// <reference path="./objc!nsswiftsupport.d.ts" />
现在,我们可以调用我们的代码,因此在 app/main-view-model.ts
中将点击方法更改为
onTap() {
// Create an instance of the Swift class we created.
const message = NSCSwiftMessages.new();
// Assign a callback to get notified when the message closes
message.onDoneCallBack = (message: string) => {this.message = message;};
// Show the actual message
message.showMessageWithTitleBody("This is the Title", "Hello There!");
}
现在,当我们运行应用程序并点击按钮时,我们漂亮的全新消息就会显示出来!
当它隐藏时,我们会得到一个回调,该回调会更改标签。