来源:黄文臣

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. iOS开发中FMDB的使用

    1.什在日常的开发中,我们需要用到离线缓存将数据信息存入数据库,在没有网络的时候进行加载,而我们IOS用的就是sqlite3数据库,用原生的sql我们也能实现,但是书写起来比较麻烦,尤其是其它语言转过 ...

  2. [Spring Boot] Complex Scope Scenarios of a Spring Bean - Mix Prototype and Singleton, ScopeProxy

    We have the following example: @SpringBootApplication public class In28minutesScopeApplication { pri ...

  3. Ubuntu 突然上不去网了怎么办

    到家了也想看看程序.打开WIN8上的虚拟机VM,然后启动Ubuntu.................................... 像往常一样等待着界面,输入password,然后改动程序. ...

  4. window.btoa

    概述 将ascii字符串或二进制数据转换成一个base64编码过的字符串,该方法不能直接作用于Unicode字符串. 语法 var encodedData = window.btoa(stringTo ...

  5. 理解linux sed命令

    理解linux sed命令(2010-02-27 18:21:20) 标签:linuxshellsed替换 分类:革命本钱 1. Sed简介sed是一种在线编辑器,它一次处理一行内容.处理时,把当 前 ...

  6. .Net 如何实现 LINQ~

    本文内容 引入 实现 LINQ 的两个前提 扩展方法 λ 表达式 LINQ 参考资料 本文说明 LINQ 是如何实现的,知道这点,才能更好地使用它~ 如果你刚接触 LINQ,那么可能不会那么快就理解. ...

  7. PHPCMS源码分析

    PHPCMS 一.模版引擎 如:调用单页面index.php?m=content&c=index&a=lists&catid=9.1.先获取到模版变量的值$template_l ...

  8. Objective-C编程 - 1. 浅谈内存分配

    Objective-C语言的对象类型都必须用指针,对象所占的内存是在堆(heap)上分配的. NSString也必须在堆上分配,因此必须用指针. NSString *someString = @&qu ...

  9. CSS外框高度自动适应

    当有浮动float时,最外框会不跟随内容的高度而高: 解决办法一:清除浮动  clear:both <!DOCTYPE html> <html xmlns="http:// ...

  10. MicrosoftAjax.js

    MicrosoftAjax.js下载 Function.__typeName = "Function"; Function.__class = true; Function.cre ...