来源:黄文臣

blog.csdn.net/hello_hwc/article/details/58320433

前言

为什么要写这样一篇文章,因为昨天和一个朋友讨论到Swift和Objective C如何混合开发Framework,中途发现了很多有意思的坑。

用Swift封装OC的库是一件比较常见的事情,毕竟对于大多数公司来说,老的代码都是用OC写的,而且经过多次迭代,这些OC的代码已经被验证了是稳定的,用Swift重写代价太大。这就引入了一个需求:

  • 用Swift和OC来混编一个Framework。

如果你之前没有用Swift和Objective C混合开发,建议看看这篇文档:

  • Swift and Objective-C in the Same Project

    https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html


按照文档一步一步来

新建一个基于单页面工程,然后新建一个一个Target,选中Cocoa Touch Framework。然后,分别新建一个Swift文件和Objective C类,注意Target Member Ship选中Framework。类的内容如下:

OCSource.h

#import <span class="hljs-title"><Foundation/Foundation.h></span>

@interface OCSource : NSObject

- (void)functionFromOC;

@end

OCSource.m

#import "OCSource.h"

@implementation OCSource

- (void)functionFromOC{

NSLog(@"%@",@"Log from objective c in framework");

}

@end

Swift调用OC

新建SwiftSource.swift

open class SwiftIt{

public init(){}

let ocObject = OCSource()

public func encapsulate(){

ocObject.functionFromOC()

}

}

然后,按照文档中,为了让Swift文件访问Objective C文件,我们应该在umbrella header,也就是MixFramework.h中,暴露所需要的header。

也就是,MixFramework.h,

#import <MixFramework/OCSource.h>

然后,自信满满的点击build。

Boom~~~,编译不通过。

原因:OCSource.h默认编译的时候是Project权限. 为了在umbrella header中使用,要把这个文件的权限改成Public

按照图中的方式拖过去即可。

嗯,现在build,可以看到build成功了。

OC调用Swift

在SwiftSource.swift中,增加一个类,

open class ClassForOC:NSObject{

public static let textForOC = "textForOC"

}

然后,为了在OC中调用Swift的方法,我们需要导入头文件,这时候,OCSource.m文件内容如下

#import "OCSource.h"

#import <MixFramework/MixFramework-Swift.h>

@implementation OCSource

- (void)functionFromOC{

NSLog(@"%@",[ClassForOC textForOC]);

}

@end

然后,build,发现成功了,很开心。


外部调用

在ViewController.swift中,我们调用Framework中的内容。

import MixFramework

class ViewController: UIViewController {

var t = SwiftIt()

override func viewDidLoad() {

super.viewDidLoad()

t.encapsulate()

// Do any additional setup after loading the view, typically from a nib.

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

// Dispose of any resources that can be recreated.

}

}

然后运行,发现控制台打印出

2017-03-02 16:08:24.000 HostApplication[19524:167669] textForOC

嗯,framework打包成功了。


问题

通常,我们希望暴露给外部的接口是纯Swift,而OC文件的具体接口应该隐藏,这就是我标题中的优雅两个字的含义。

如果你好奇,你会发现,在ViewController.swift中你可以这么调用

var s = OCSource()

也就是说,OC的内容也暴露出来了,这破坏了Framework的封装特性。

通过查看MixFramework的编译结果,发现最后暴露出的接口是这样子的

import Foundation

import MixFramework.OCSource

import MixFramework

import MixFramework.Swift

import SwiftOnoneSupport

import UIKit

//

//  MixFramework.h

//  MixFramework

//

//  Created by Leo on 2017/3/2.

//  Copyright © 2017年 Leo Huang. All rights reserved.

//

//! Project version number for MixFramework.

public var MixFrameworkVersionNumber: Double

open class ClassForOC : NSObject {

public static let textForOC: String

}

open class SwiftIt {

public init()

public func encapsulate()

}

这一行,把OC对应的实现暴露出来了

import MixFramework.OCSource


优雅的解决方案

不再通过umbrella header的方式让framework中的Swift调用OC方法。而是通过modulemap。

新建一个module.modulemap文件,内容如下

module OCSource [system] {

//由于module.modulemap和OCSource.h是在同一个文件夹的,如果不是同一个,路径要写全

header "OCSource.h"

export *

}

这里的#(SRCROOT)是XCode的宏,会自动替换成项目所在的根目录,这里输入的路径是module.modulemap文件所在的路径。

然后,删除MixFramework.h(umbrella header)中#import 的OC header。

把OCSource.h的权限改回默认的project。

再编译,发现OC的类被隐藏了。


总结

如果你要开发一个framework,一定要想清楚哪些接口暴露出去,哪些封装起来,framework不是简单把一包文件加个壳子。

开发 Swift 和 Objective-C 混编的 Framework的更多相关文章

  1. Swift _ OC _ 混编

    Swift _ OC _ 混编 在OC环境下使用Swift. GitHub源码

  2. 详解Swift和OC的混编

    前言: 我们在一些情况下,仅仅使用swift 是无法完成一个项目的,在swift项目中必要用到 OC 实现一些功能,比如,项目要使用一些第三方的框架,但这个第三方的框架却是用 OC 实现的,或者你的项 ...

  3. iOS开发--Swift 如何完成工程中Swift和OC的混编桥接(Cocoapods同样适用)

    由于SDK现在大部分都是OC版本, 所以假如你是一名主要以Swift语言进行开发的开发者, 就要面临如何让OC和Swift兼容在一个工程中, 如果你没有进行过这样的操作, 会感觉异常的茫然, 不用担心 ...

  4. swift和oc的混编

    一.Swift工程中加入oc代码 1.在将oc代码加入到Swift工程的时候Xcode会自动创建一个桥接文件“yourProgectName-Bridging-Header.h”,如果没有创建或者删除 ...

  5. Objective-c开发教程--MRC和ARC混编

    iOS5.0以后就开始可以使用ARC来代替之前的MRC. 1.ARC中使用MRC的类.方法如下: 在targets的build phases选项下Compile Sources下选择要不使用arc编译 ...

  6. obeject-c 与 swift 混编

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 ...

  7. swift实现与OC的混编

    swift与OC的混编 现在写swift,很多的类库还不是很全,很多的第三方还是只有OC版的,这个时候swift想用,通常都是采用的swift和OC混编的方式.这里给大家演示一下混编是如何做的. sw ...

  8. 详解 swift2.2 和 OC 的混编

    前言: 我们在一些情况下,仅仅使用swift 是无法完成一个项目的,在swift项目中必要用到 OC 实现一些功能,比如,项目要使用一些第三方的框架,但这个第三方的框架却是用 OC 实现的,或者你的项 ...

  9. iOS开发——技术精华Swift篇&Swift 2.0和Objective-C2.0混编之第三方框架的使用

    swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引 ...

随机推荐

  1. jquery中对 iframe的操作

    我们先看一下 JQUERY中的对像 contents() 的帮助文件 contents() 概述 查找匹配元素内部所有的子节点(包括文本节点).如果元素是一个iframe,则查找文档内容 示例 描述: ...

  2. telnet 163发送邮件

    1.telnet smtp.163.com 25 2. 3.测试成功

  3. CSOM中如何取到managed metadata类型字段的类型信息

    Field.fieldTypeKind返回的是Invalid [解决方法] There is no "Metadata" type of field in the SP.Field ...

  4. oauth2-server-php-docs 集成3

    Yii集成 对于Yii集成,请通过Filsh查看Yii OAuth2服务器资源库 CakePHP的 有关CakePHP中集成的这个库的示例,请参阅Qsoomro CakePHP OAuth2 Demo ...

  5. OpenWrt Web界面修改及功能实现实例说明

    http://www.cnblogs.com/dwayne/archive/2012/04/21/2460830.html 通过上篇文章的介绍,我们应该了解了Lua语言在OpenWrt Web配置页面 ...

  6. myeclipse集成jdk、tomcat8、maven、svn

    今天一个同学要回家了.回家之前叫我帮他配置一下开发环境.然后在家里面自己研究一下.敲下代码. 帮他配置好之后自己回来把这个过程写下来.别让自己把这个东西给忘了. myeclipse安装 myeclip ...

  7. Provide your license server administrator with the following information.error code =-42,147

    ArcEngine应用程序开发中,许可不必不可少的.一般采取两种方式来获取许可——License控件和AoInitialize类,但今天在VS2010打开程序时,隔一会弹出错误窗口:Provide y ...

  8. 修改mysql的默认端口号

    mysql的默认端口号是3306,修改端口号的话,找到mysql的安装目录,找到my.ini文件 修改这两处的3306值,重启mysql即可

  9. git ingore添加忽略文件无较的解决方法

    一.启动Git Bash并切换到项目目录下 二.执行下列语句: git rm -r --cached . git add . git commit -m 'update .gitignore' 三.O ...

  10. Emmet (前身为 Zen Coding)

    使用示例: 在编辑器中输入缩写代码:ul>li* ,然后按下拓展键(默认为tab),即可得到代码片段: <ul> <li></li> <li>&l ...