来源:黄文臣

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. 汇总c#.net常用函数和方法集

    1.DateTime 数字型 System.DateTime currentTime=new System.DateTime(); 1.1 取当前年月日时分秒 currentTime=System.D ...

  2. 斯坦福大学CS224d课程目录

    https://www.zybuluo.com/hanxiaoyang/note/404582 Lecture 1:自然语言入门与次嵌入 1.1 Intro to NLP and Deep Learn ...

  3. Linux系统中关于Sqlite3中文乱码问题及解决办法

    新做的一个项目在本地(Win8)测试时没有问题,但传到服务器(Linux)时从Sqlite3数据库查询到的数据中文却是乱码(数据库中是正常的) 将php文件.html文件都设置成统一的utf8还是一样 ...

  4. 利用Docker搭建java项目开发环境

    一.需求 一台 Ubuntu 16.0.4 LTS ,安装了Docker服务,Rancher服务,也制作了Tomcat相关的image,接下来我们就来说一下如何快速的构建一个开发环境和测试环境 二.步 ...

  5. (转)unityshaderLab中fixed function常用指令

    ShaderLab中常用的fixedFunction. SubShader{ Tags{"Queue"="Transparent"} //渲染完不透明物体,再渲 ...

  6. The future of scripting in Unity

    Recently we talked about Unity and WebGL . In that post we briefly spoke about how scripting works i ...

  7. Asp.net MVC利用WebUploader上传大文件出现404解决办法。

    刚开始我上传小文件都是比较顺利的,但是上传了一个大文件大约有200M的压缩包就不行了.在chrome里面监视发现网络状态是404,我分析可能不是WebUploader的限制,应该是WebConfig限 ...

  8. Mockito单测,mock service层的mapper

    转载:https://blog.csdn.net/paincupid/article/details/53561435 1.引入mockito jar包 <dependency> < ...

  9. HTTP 响应实体主体:XML 及 XML parser

    本文内容 HTTP 响应实体主体:XML XML parser 总结 各编程语言实现的 XML parser   HTTP 响应实体主体:XML 实体主体(entity-body)通常是HTTP响应里 ...

  10. 微服务架构实践 - 你只懂docker与spring boot就够了吗?

    微服务架构实践 - 你只懂docker与spring boot就够了吗? 作者 浮云发发 已关注 2017.02.27 02:50* 字数 2613 阅读 2583评论 6喜欢 35赞赏 2 微服务并 ...