为多平台(iOS、macOS、watchOS、tvOS)创建通用的 Swift Framework

2017-10-30 10:24:53来源:http://blog.ioshub.cn/2017/10/14/0011/作者:iOSHub人点击

分享

原文来自: Create a Universal Swift Framework for iOS, OS X, watchOS, and tvOS


译者按:其实 macOS 和 iOS 除了使用的编程语言一样之外,也拥有着不少通用的框架、公共库,在开发双平台应用的时候,model 和很多逻辑可以通用,这样就产生了代码共用的需要。最近我在做一个应用同时拥有 macOS 和 iOS 两个客户端,在 Medium 里找到这篇文章觉得不错,因此翻译了一下。


Xcode 7.2 内提供了为任何平台(iOS, OS X, watchOS, tvOS)创建 Swift Framework 的支持。


然而,Xcode 并没有提供创建同时支持多平台的、通用的 framework 的功能。


通用库(Universal framework)是发布开放库的一种最佳的方式。事实上,多亏了包管理工具 Carthage,开发者想发布一款多平台的库只需要保证它可以编译即可。满足这个需要的库只要求开发者在 Carthage 里配置对应的 Git URL 即可。


然而,这样的操作方法还是缺乏愉悦感。Apple 似乎有意用 Swift Package Manager 来取代这样单调的过程,不过还处在 Beta 版的它还是有很长的路要走。下文将一步步地介绍如何创建一个通用的 framework. 这里边有我自己的探索,也有一部分引用了他人的做法。你将不用几分钟的时间就能完成今天的教程。


Let’s go.


Step 1

从模版中建立新的 Xcode 项目,并选择:


iOS -> Framework & Library -> Cocoa Touch Framework



Step 2

为你的项目起个名字并在名字后面加入「_iOS」。需要留意已经为「Include Unit Tests box」 打了勾勾。


NOTE: 不要 在你的项目名里包含「-」,因为会产生一个一样的名字的 target,而破折号是一个非法的命名。


你不必担心,我们将在后面对项目名称进行修改,甚至你可以回来添加破折号(虽然 iOS target 名字还是保持不变)。



Step 3

在 Xcode 顶部菜单里,选择 File -> New -> Target



Step 4

选择你想支持的平台的 framework 模版。比如我们选择了 macOS:


OS X -> Framework & Library -> Cocoa Framework



Step 5

然后,我们要像前面一样为项目命名,在项目名的最后加上「_Mac」:



Step 6

重复 Step 4 和 5 来添加每个你想要支持的平台


Step 7
现在我们将开始重构项目的框架:

1、删除「_Mac」文件夹,选择「Move to Trash」



2、打开 Finder,进入项目文件夹,删除「_Mac」文件夹(译者注:在 Xcode 9 里,如果你已经选择删除文件时同时丢入垃圾桶,此时这两个文件夹已经不存在)



3、在当前的文件夹中把「ProjectName_iOS」重命名为「CommonSource」,把「ProjectName_iOSTests」重命名为「CommonTests」



4、回到 Xcode 中,删除那些空的文件夹



5、先把 CommonSource 这个文件夹拉入到项目中(译者注:不需要拉 test 文件夹), 不要选择任何的 「Add to target」



6、现在可以重命名项目,删掉「_iOS」后缀,改成你想要的名字。当然你可以保留这样的命名方式。



确定后会提醒是否重命名项目内容,选择「Don’t Rename」



7、为「ProjectName_iOS.h」删除其后缀名



8、现在把 CommonTests 文件夹拉到项目中。同样的, 不要选择任何的「Add to target」



9、关闭 Xcode 项目,为项目的文件夹名删掉「_iOS」后缀。此时你的文件夹应该长这样:



Step 8

到目前为止,我们已经重构完成项目结构。


接下来我们需要修复一下两个文件的 target memberships。再次打开 Xcode。


1、选择 CommonSource -> ProjectName.h 文件,然后在右手边的配置中,选择未被标记的 target memberships,并标记为 Public。



2、选择 CommonTests -> SwiftyGmail_iOSTests.swift 文件,同样标记。



此时该文件会报错误,你需要重命名引用的库,删掉后缀「_iOS」



Before



After


Step 9

在 Build Setting 中同时选择两个 target,找到 Packaging -> Info.plist file 然后把其中改为 CommonSource/Info.plist



Step 10

在 Build Setting 中同时选择两个 target,找到 Packaging -> Product Name 然后把其中改为你的项目名(没有后缀的)



(可选)Step 11: 支持 Carthage

如果你想为你的框架支持 Carthage,你需要修改你的 Schemes 为 Shared


1、在 Xcode 窗口的左上角点击当前的 Scheme,再点击 Manage Schemes



2、现在为每个 scheme 标记为 Shared



Step 12:把该死的源代码拉进来吧!

OK,你已经完成了本文的内容!


你可以编译、测试你的库是否支持你想要的平台


当你添加新的源码时,确保它拉到每个你想要的平台中。单元测试的代码也是一样道理。


以上本文译完。


以下为本人在使用过程的踩坑总结,做一个补充。


1、Xcode 9 的臭虫


当你使用 9A235 版本的 Xcode 9 时,把文件拉到项目里,就算勾选了 Add to taeget 文件还是没有正确添加进去,此时你要在文件 -> 项目右侧手动添加。


2、创建 Swift 的 framework 时,公共方法必须标记为 public。详情可以查看这篇文章: Creating and Distributing iOS Frameworks


3、经常需要判断对应平台来引用正确的框架,比如 Cocoa for macOS 之于 UIKit for iOS。除了引用,一些逻辑可能也要进行判断。Swift 和 OC 有不一样的代码,下面是实例:


OC:
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#elif TARGET_OS_MAC
#import <Cocoa/Cocoa.h>
#endif
Swift:
#if os(iOS)
import UIKit
#elseif os(OSX)
import Cocoa
#endif

4、Core Data 的 model 无法在 framework 里共用,会出现无法加载 model 的错误。我目前做法是 model 还是分别放在主项目里。(如果你有更好的解决方法麻烦告诉我,谢~)


更多个人分享,可以瞧瞧我不怎么更新的技术博客:iOSHub。当然还有非技术的ChanTalk。


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台