【发布时间】:2014-06-06 04:01:42
【问题描述】:
我想要什么: 使用 Swift 在 Android 和 iOS 之间共享非 UI 代码。
问题: Android 具有 NDK 支持,允许您使用 Java 本机接口 (JNI) 运行 C 和 C++ 代码(不是 Objective C)。我是一名 Java 程序员,不太了解编译 C 代码的来龙去脉。为了能够通过 JNI 访问 swift 方法,我需要执行哪些一般步骤?
【问题讨论】:
我想要什么: 使用 Swift 在 Android 和 iOS 之间共享非 UI 代码。
问题: Android 具有 NDK 支持,允许您使用 Java 本机接口 (JNI) 运行 C 和 C++ 代码(不是 Objective C)。我是一名 Java 程序员,不太了解编译 C 代码的来龙去脉。为了能够通过 JNI 访问 swift 方法,我需要执行哪些一般步骤?
【问题讨论】:
您可以使用 RemObjects Silver 来代替 JNI。你在那里写的 swift 代码不是用 Apple 的 Swift 工具链编译的,而是他们有自己的编译器工具链,叫做 Elements,所以 Element 的 Swift 也被称为 Silver 与苹果的 swift 有一些不同。它已经过扩展,可以很好地融入 Java 和 .NET 世界。您可以在此处阅读更多相关信息 - Silver Language Extentions。
您可以使用来自 Visual Studio 或它们自己的 OS X IDE(称为 Fire)的元素。让我用 Fire 来演示一个非常简单的例子。 (Download Elements)
1. 开火并创建一个新项目。在项目模板中,选择共享项目。 (平台的选择无所谓)
2. 在 File -> New File 下使用 Code File 模板创建一个新的空源文件。我们称它为记录器。 (确保选择的语言是swift)
3. 将该文件的内容替换为:
#if COOPER
import java.util
#elseif ECHOES
import System.Collections.Generic
import System.Linq
import System.Text
#elseif NOUGAT
import Foundation
#elseif !ELEMENTS
#endif
public class Logger {
public class func logIt(stuff: String){
#if NOUGAT
NSLog("\(stuff)")
#elseif ECHOES
Console.WriteLine("\(stuff)")
#elseif COOPER
System.out.println("\(stuff)")
#elseif !ELEMENTS
print("\(stuff)")
#endif
}
}
这是适用于每个平台的记录器抽象的最简单示例。使用预处理器指令,您可以指定将编译到每个特定平台的代码。NOUGAT 代表 CocoaECHOES 代表 .NETCOOPER 代表 Java
您也可以使用!ELEMENTS 表示您将使用其他工具链有条件地编译的代码,例如,如果您想使用 Apple 的 Swift 构建代码。
在 Fire -> Preferences 下,转到第 4 个选项卡并确保您有 Fire 发现的 JDK、JRE 和 Android 文件夹。
构建解决方案。 Android 类库将构建您现在可以在 Android Studio 项目中使用的 .jar 文件。
导航到您的 Android 类库项目目录,然后将 .jar 文件从 obj/Dubug/Android 复制到您的 Android 项目 libs 文件夹中。
在 Android Studio 中,右键单击 .jar 文件并按 添加为库。然后确保您的 build.gradle 在其依赖项中有 compile files('libs/swiftcommons.android.jar')。
这就是 Logger 在反编译时的样子。
package swiftcommons.android;
public class Logger {
public static void logIt(String stuff) {
if(stuff == null) {
throw new IllegalArgumentException("stuff");
} else {
System.out.println(String.format("%s", new Object[]{stuff}));
}
}
public Logger() {
}
}
所以现在您可以从您的代码中调用您的 Logger:
import swiftcommons.android.Logger;
//.....
Logger.logIt("It works..");
作为一个好的策略,我建议您编写共享代码库,该代码库将与 Apple 的 swift 工具链 (#IF !ELEMENTS) 和适用于 Android 的 Elements 一起编译。 (#IF COOPER)。 Elements 还为您提供 SwiftBaseLibrary 和名为 Sugar 的实用程序库,您可以在使用 Elements 进行编译时使用它们。
【讨论】:
您需要将 Swift 库导出为 .so,然后您必须编写一个包装器 (JNI) 来在 Java 层和库之间进行交互。对于包装部分,安装NDK.
【讨论】:
RemObjects 的人们已经宣布Silver。这是他们的 Elements 编译器套件的 Swift 兼容前端。 Elements 为 JVM、Android、.Net、iOS、OSX 平台生成程序。您可以使用此工具集在 C#、Oxygen(他们的 ObjectPascal 版本)和现在的 Swift 中编写应用程序!
我一直在使用 Silver 的预发布版本,看到 Swift 代码在我的 Android 设备上运行很有趣。期待从系统中消除一些皱纹并在 Android 上发布我的第一个 Swift 应用程序。请注意,您对本机 UI 工具包进行编程......除了一些基本数据结构(如开源 RemObjects Sugar 库中的数组和字典)之外,没有可使用的多平台代码。
【讨论】: