原创 2017-06-28
关键点
- Swift依赖第三方Objective-C Framework、Library创建Pod
- Swift与Objective-C代码混合创建Pod
- Swift与OC、第三方Framework/Library混合创建Pod
在我的另一篇文章中介绍到了如何创建自己的公有、私有Pod,我以为创建Pod的坑就可以很简单的跳过,但是事情不是这样子的,在使用组件化开发私有组件的时候我又遇到了新问题(由于项目采用的是Objective-C开发):
- 业务组件依赖其他第三方厂家提供的OC Frameworwk、Library,这些第三方只提供了OC工具包,这个时候我们应该怎样让他集成到我们自己的其中一个业务组建中?
- 在私有业务组件开发中,遇到了项目急需演示验收,这个时候你并没有足够的时间采用Swift来实现你的业务(已经实现了一部分),但是在以前的OC开发项目中,你已经实现了此业务另一部分,现在你需要做的是把它们拿过来集成到你现在开发的一个业务组件中来 ,但是如何集成呢?
下面来说一说解决办法:
准备工作
在这里我们需要有一个Development Pod让我们来进行开发、测试,首先我们通过pod lib 来创建一个Pod,使其包含Example,Pods等,当然你也可以自己手动完成这一系列事情。
pod lib create Verify-SwiftOC3rd
Cloning `https://github.com/CocoaPods/pod-template.git` into `Verify-SwiftOC3rd`.
Configuring Verify-SwiftOC3rd template.
------------------------------
To get you started we need to ask a few questions, this should only take a minute.
If this is your first time we recommend running through with the guide:
- http://guides.cocoapods.org/making/using-pod-lib-create.html
( hold cmd and click links to open in a browser. )
What language do you want to use?? [ Swift / ObjC ]
> Swift
Would you like to include a demo application with your library? [ Yes / No ]
> Yes
Which testing frameworks will you use? [ Quick / None ]
> None
Would you like to do view based testing? [ Yes / No ]
> No
Running pod install on your new library.
上述所有的步骤你只需要按照提示信息完成即可,创建成功后将会自动打开项目,最后你看到的将会是:
然后我们将其与Github关联起来,你需要在github上创建一个新的Repo - Verify-SwiftOC3rd:
$ git remote add origin git@github.com:ApterKingRepo/Verify-SwiftOC3rd.git
接下来将.podspec 稍加修改:将其中的homepage,source等信息配置一下,最后验证修改是否正确,然后提交代码:
$ pod lib lint --swift-version=3.0
-> Verify-SwiftOC3rd (0.1.0)
Verify-SwiftOC3rd passed validation.
$ git add .
$ git commit -m "Initial"
$ git push
至此准备工作完成!
Swift依赖第三方Objective-C Framework、Library创建Pod
在制作我自己私有Pod时,我们往往需要用到第三方提供的工具包,比如说网络请求Moya,数据解析SwiftyJSON,响应式编程(RP) RxSwfit等,对于这些框架的使用我们在制作创建我们Pod的时候,往往只需要在我们的.podspec中dependency既可以了,如我在SwiftyJSON基础之上创建的SwiftyJSONMappable(用于JSON与Model互相转换,并且提供了与Moya的配合使用)这个Pod,我只需要在我的Pod中使用dependency
即可:
Pod::Spec.new do |s|
...
// 此处省略
...
s.requires_arc = true
s.default_subspec = "Mappable"
s.subspec "Mappable" do |ss|
ss.source_files = "Pod/Classes/JSONMappable.swift"
ss.dependency "SwiftyJSON", "~>3.1.4"
ss.frameworks = "Foundation"
end
...
end
当在创建我们自己的Pod时,Pod会自己检测并且install
我所引用到的第三方仓库,一切顺利。但是也许你会使用到像百度地图、高德地图、ShareSDK分享等使用Framework以及library方式集成的第三方库,它们其中有些是提供了你使用Pod方式导入的,可能你会想到直接dependency一下,这里我们就来以百度地图为例做一个验证:
Pod::Spec.new do |s|
...
s.requires_arc = true
s.dependency "BaiduMapKit" // 主要看这里就好
end
现在你想到的应该是执行pod lib lint
就可以了吧,ok我们来执行以下
$ pod lib lint Verify-SwiftOC3rd.podspec
-> Verify-SwiftOC3rd (0.0.1)
- ERROR | [iOS] unknown: Encountered an unknown error (The 'Pods-App' target has transitive dependencies that include static binaries: (/private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/thirdlibs/libcrypto.a, /private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/thirdlibs/libssl.a, /private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Base.framework, /private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Cloud.framework, /private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Location.framework, /private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Map.framework, /private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Radar.framework, /private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Search.framework, and /private/var/folders/pq/1jkyxxs52bd9c4jykqvgfqbw0000gn/T/CocoaPods/Lint/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Utils.framework)) during validation.
[!] Verify-SwiftOC3rd did not pass validation, due to 1 error.
You can use the `--no-clean` option to inspect any issue.
结果是验证不通过!!!为什么呢?那是因为在Pod中你是使用了动静态库.framework、.a,这个是在制作Pod时需要指明的,你需要使用到(官方文档可查):
vendored_frameworks = "xxx.framework"
vendored_libraries = "xxx.a"
他们需要的是一个路径,相对路径,也就是说如果你在制作Pod时,如果第三方工具包使用的是动态库.framework或者静态库.a,那么你就不能简单的通过dependency
方式来引入它了,不管它是Objective-C还是Swift Language,你现在要做的是下载到他们的framewor或者library,然后通过上面的一种或者两种方式来引入进来,对于这个问题,我想就使用百度地图来说明一下解决情况吧:
- 首先你需要根据自己的需求去官网下载百度地图SDK(这里我只下载基础地图包)
- 将其放置于你需要制作Pod项目的一个子目录下
处理完成之后项目目录结构大致是:
- 修改.podspec文件
我这里把百度地图制作成为一个subspec,当然你也可以不用这样,我这样做的原因是:因为我还有我与业务相关的source_files,我把百度地图作为一个subspec更好区分一点而已
Pod::Spec.new do |s|
s.name = "Verify-SwiftOC3rd"
s.version = "0.0.1"
s.summary = "验证私有组件中使用Swift结合OC第三方.framewor、.library库及OC文件组合打包构建私有Pod"
...
s.requires_arc = true
s.subspec 'BaiduMapKit' do |ss|
ss.source_files = ''Verify-SwiftOC3rd/Vendors/*.framework/Headers/**.h'
ss.public_header_files = ''Verify-SwiftOC3rd/Vendors/*.framework/Headers/**.h'
ss.frameworks = 'CoreLocation', 'QuartzCore', 'OpenGLES', 'SystemConfiguration', 'CoreGraphics', 'Security', 'CoreTelephony'
ss.libraries = 'sqlite3.0', 'stdc++.6.0.9'
ss.vendored_frameworks = 'Verify-SwiftOC3rd/Vendors/*.framework'
ss.vendored_libraries = 'Verify-SwiftOC3rd/Vendors/thirdlibs/*.a'
ss.preserve_paths = 'Verify-SwiftOC3rd/Vendors/*.framework', 'Verify-SwiftOC3rd/Vendors/thirdlibs/*.a'
ss.pod_target_xcconfig = { 'LD_RUNPATH_SEARCH_PATHS' => '$(PODS_ROOT)/Verify-SwiftOC3rd/Vendors/' }
end
end
好了现在让我们来验证一下是否可以成功:
$ pod lib lint
-> Verify-SwiftOC3rd (0.1.0)
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
- NOTE | xcodebuild: <module-includes>:1:9: note: in file included from <module-includes>:1:
- NOTE | xcodebuild: /Users/wangcong/Library/Developer/Xcode/DerivedData/App-bqxcyvfrcjeqxqbqkrseipvvyrla/Build/Products/Release-iphonesimulator/Verify-SwiftOC3rd/Verify_SwiftOC3rd.framework/Headers/Verify-SwiftOC3rd-umbrella.h:22:9: note: in file included from /Users/wangcong/Library/Developer/Xcode/DerivedData/App-bqxcyvfrcjeqxqbqkrseipvvyrla/Build/Products/Release-iphonesimulator/Verify-SwiftOC3rd/Verify_SwiftOC3rd.framework/Headers/Verify-SwiftOC3rd-umbrella.h:22:
- NOTE | xcodebuild: /Users/wangcong/Library/Developer/Xcode/DerivedData/App-bqxcyvfrcjeqxqbqkrseipvvyrla/Build/Products/Release-iphonesimulator/Verify-SwiftOC3rd/Verify_SwiftOC3rd.framework/Headers/BMKArcline.h:9:9: note: in file included from /Users/wangcong/Library/Developer/Xcode/DerivedData/App-bqxcyvfrcjeqxqbqkrseipvvyrla/Build/Products/Release-iphonesimulator/Verify-SwiftOC3rd/Verify_SwiftOC3rd.framework/Headers/BMKArcline.h:9:
- ERROR | [iOS] xcodebuild: /Users/wangcong/Library/Developer/Xcode/DerivedData/App-bqxcyvfrcjeqxqbqkrseipvvyrla/Build/Products/Release-iphonesimulator/Verify-SwiftOC3rd/Verify_SwiftOC3rd.framework/Headers/BMKMultiPoint.h:10:9: error: include of non-modular header inside framework module 'Verify_SwiftOC3rd.BMKMultiPoint': '../../../../../../../../../Users/wangcong/Development/iOS/Verify/Verify-SwiftOC3rd/Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Headers/BMKTypes.h'
完美的出现了两个错误
- include of non-modular header inside framework module 'xxx.framework'
- error: redefinition of enumerator 'BMK_COORDTYPE_GPS'
要解决这两个错误很简单,你只需要去掉你BaiduMapKit中的两个参数ss.source_files以及ss.public_header_files
Pod::Spec.new do |s|
s.name = "Verify-SwiftOC3rd"
s.version = "0.0.1"
s.summary = "验证私有组件中使用Swift结合OC第三方.framewor、.library库及OC文件组合打包构建私有Pod"
...
s.requires_arc = true
s.subspec 'BaiduMapKit' do |ss|
ss.frameworks = 'CoreLocation', 'QuartzCore', 'OpenGLES', 'SystemConfiguration', 'CoreGraphics', 'Security', 'CoreTelephony'
ss.libraries = 'sqlite3.0', 'stdc++.6.0.9'
ss.vendored_frameworks = 'Verify-SwiftOC3rd/Vendors/*.framework'
ss.vendored_libraries = 'Verify-SwiftOC3rd/Vendors/thirdlibs/*.a'
ss.preserve_paths = 'Verify-SwiftOC3rd/Vendors/*.framework', 'Verify-SwiftOC3rd/Vendors/thirdlibs/*.a'
ss.pod_target_xcconfig = { 'LD_RUNPATH_SEARCH_PATHS' => '$(PODS_ROOT)/Verify-SwiftOC3rd/Vendors/' }
end
end
是什么原因呢?在创建Pod时候,我们并不需要创建xxx-Bridge-Header, 这个工作交由xxx-umbrella.h完成,这个文件的作用是:混合你的Swift以及OC,并且向外界暴露你的APIs,当你再次通过ss.source_files以及ss.public_header_files时会重复定义,现在我们去掉之后来试试是否能够成功:
$ pod lib lint
-> Verify-SwiftOC3rd (0.1.0)
Verify-SwiftOC3rd passed validation.
OK , 成功!接下来将你的代码push到名叫Verify的specs中
$ git add .
$ git commit -m "提交百度.framework、.a 并且完成subspec BaiduMapKit"
$ git push // 这里会等上一会
$ git tag 0.1.0
$ git push --tags
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:ApterKingRepo/Verify-SwiftOC3rd.git
* [new tag] 0.1.0 -> 0.1.0
$ pod repo push Verify Verify-SwiftOC3rd.podspec
- 现在你我们来验证是否可以使用了:
编译运行,一切OK!到这里已经算是可以使用了。这里我们来进行稍微的优化一下,你可能会想到如果你的项目是采用Swift来完成的,那么你就必须需要创建xxx-Bridge-Heder.h,有没有一种方式是可以不需要Bridge-Header的呢?这里我么使用创建一个.modulemap来解决进行优化:
- 修改.podspec,为你所引用到的framework创建Module,这里我把.podsepc全部提出来,为了使你了解的更明白:
注意:
如果我们手动创建一个module文件,直接移进去。这样会导致 pod install 时可能丢失该文件,那么该怎么办呢?我们需要使用的是prepare_command,来帮助我们自动创建
Pod::Spec.new do |s|
s.name = 'Verify-SwiftOC3rd'
s.version = '0.1.4'
s.summary = '验证私有组件中使用Swift结合OC第三方.framework、.library库及OC文件组合打包构建私有Pod'
s.homepage = 'https://github.com/ApterKingRepo/Verify-SwiftOC3rd'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'ApterKing' => 'wangcccong@outlook.com' }
s.source = { :git => 'https://github.com/ApterKingRepo/Verify-SwiftOC3rd.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'Verify-SwiftOC3rd/Vendors/*.framework/Headers/**.h'
s.public_header_files = 'Verify-SwiftOC3rd/Vendors/*.framework/Headers/**.h'
s.resources = 'Verify-SwiftOC3rd/Vendors/*.framework/Resources/mapapi.bundle'
s.frameworks = 'CoreLocation', 'QuartzCore', 'OpenGLES', 'SystemConfiguration', 'CoreGraphics', 'Security', 'CoreTelephony'
s.libraries = 'sqlite3.0', 'stdc++.6.0.9'
s.vendored_frameworks = 'Verify-SwiftOC3rd/Vendors/*.framework'
s.vendored_libraries = 'Verify-SwiftOC3rd/Vendors/thirdlibs/*.a'
s.prepare_command = <<-EOF
# 创建Base Module
rm -rf Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Modules
mkdir Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Modules
touch Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Modules/module.modulemap
cat <<-EOF > Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Modules/module.modulemap
framework module BaiduMapAPI_Base {
umbrella header "BMKBaseComponent.h"
export *
link "sqlite3.0"
link "stdc++.6.0.9"
}
\EOF
# 创建Map Module
rm -rf Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Modules
mkdir Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Modules
touch Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Modules/module.modulemap
cat <<-EOF > Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Modules/module.modulemap
framework module BaiduMapAPI_Map {
umbrella header "BMKMapComponent.h"
export *
link "sqlite3.0"
link "stdc++.6.0.9"
}
\EOF
EOF
end
-
pod install
,测试是否可以使用
Swift与Objective-C代码混合创建Pod
接下来我们还需要来解决文章开头提到的第二个问题,那就是如何将Swfit于OC代码混合打包(我们这一步只验证Swift与OC混合打包),在这里就直接使用上述所创建的工程,不过我们需要的先将上述与百度地图有关的信息删除,然后修改Pod文件:
- 删除Vendors文件夹
- 修改.podspec
Pod::Spec.new do |s|
s.name = 'Verify-SwiftOC3rd'
s.version = '0.1.1'
s.summary = '验证私有组件中使用Swift结合OC第三方.framework、.library库及OC文件组合打包构建私有Pod'
s.homepage = 'https://github.com/ApterKingRepo/Verify-SwiftOC3rd'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'ApterKing' => 'wangcccong@outlook.com' }
s.source = { :git => 'https://github.com/ApterKingRepo/Verify-SwiftOC3rd.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '8.0'
s.source_files = 'Verify-SwiftOC3rd/Classes/**/*'
# s.public_header_files = 'Pod/Classes/**/*.h'
end
注:
可以不用通过pod repo push
之后再来验证创建的Pod添加的代码是否正确,在你通过pod lib create POD_NAME
中是可以直接修改本地.podspec,然后在Example目录下直接pod install
,这个验证比较方便,快捷,不用依赖网络
- 接下来创建一个PersonProtocol、Kid,使Kid实现PersonProtocol协议
- 完成上述步骤后,你当然是希望外部也能够访问到我的文件,那该如何处理呢?现在只需要将他们的.h文件设置为public,如下图:
- 这个时候你执行
pod install
,然后打开你的xxx-unbrella.h,你会发现上述两个文件的头文件已经被引入进来了,你可以把xxx-unbrella.h看成是你的项目头文件或者在Swift项目中他充当一个xxx-Bridge-Header.h文件
- 接下来实现Swift对OC的引用,如果是Swift代码我们是不需要像OC一样设置其为public的只需要定义其访问权限即可,但是需要勾选其Target Membership。我在这里创建一个Woman,使其有一个小孩Kid并且实现PersonProtocol,然后喂养这个小孩吃饭:
编译发现会出现以下错误:
只需要按照提示创建一个即可
- 实现Objective-C调用Swift,为了凑成一个家庭,我还创建了一个Father.swift类, Family使用OC Language,它包含了Kid、Mother、Father这三个类,最后结构如下:
编译运行,你会发现上述错误,找不到你的ProjectName-Swift.h。原因有两点:一是在你的ProjectName-Swift.h中是引用了Family.h的,如果你这时候在定义Family.h中又引用ProjectName-Swift.h造成了有点像循环引用的概念;
二是Swift只支持动态库(并非完全意义的动态库),而我们代码在Pod之后实际上是一个动态的Framework,Swift是有命名空间的一个概念,这时候你需要做的是在引用时需要写明命名空间。基于上述两点,我们只能在OC的.m文件中引用并且加上命名空间:
- 最后我们在Example目录下
Pod install
,在项目中引用Family,然后来验证我们这个Pod是否创建成功
Swift与OC 代码、 Framework、Library混合创建Pod
上述两个分别讲解了Swift与OC代码混合创建Pod,Swift与OC Framework、Library混合创建Pod,现在我们来将三者混合创建,这里也就是我们解决了三种:
- Swift引用第三方Framework、Library
- Swift与Objective-C 在Pod相互调用
- Swift与Objective-C 在项目、Pod相互调用Framework、Library、代码
依照上述两个章节所讲,我的.podspec如下:
Pod::Spec.new do |s|
s.name = 'Verify-SwiftOC3rd'
s.version = '0.1.4'
s.summary = '验证私有组件中使用Swift结合OC第三方.framework、.library库及OC文件组合打包构建私有Pod'
s.homepage = 'https://github.com/ApterKingRepo/Verify-SwiftOC3rd'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'ApterKing' => 'wangcccong@outlook.com' }
s.source = { :git => 'https://github.com/ApterKingRepo/Verify-SwiftOC3rd.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'Verify-SwiftOC3rd/Classes/**/*', 'Verify-SwiftOC3rd/Vendors/*.framework/Headers/**.h'
s.public_header_files = 'Verify-SwiftOC3rd/Classes/**/*.h', 'Verify-SwiftOC3rd/Vendors/BadiduMapAPI_Base.framework/Headers/BMKBaseComponent.h', 'Verify-SwiftOC3rd/Vendors/BadiduMapAPI_Map.framework/Headers/BMKMapComponent.h'
s.resources = 'Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Resources/mapapi.bundle'
#s.module_name = 'BaiduMapKit'
s.frameworks = 'CoreLocation', 'QuartzCore', 'OpenGLES', 'SystemConfiguration', 'CoreGraphics', 'Security', 'CoreTelephony'
s.libraries = 'sqlite3.0', 'stdc++.6.0.9'
s.vendored_frameworks = 'Verify-SwiftOC3rd/Vendors/*.framework'
s.vendored_libraries = 'Verify-SwiftOC3rd/Vendors/thirdlibs/*.a'
s.preserve_paths = 'Verify-SwiftOC3rd/Vendors/*.framework', 'Verify-SwiftOC3rd/Vendors/thirdlibs/*.a'
s.pod_target_xcconfig = {
#'FRAMEWORK_SEARCH_PATHS' => '${PODS_ROOT}/Verify-SwiftOC3rd/Vendors',
'HEADER_SEARCH_PATHS' => '$(PODS_ROOT)/Verify-SwiftOC3rd/Vendors/*.framework/Headers',
'LD_RUNPATH_SEARCH_PATHS' => '$(PODS_ROOT)/Verify-SwiftOC3rd/Vendors/',
'OTHER_LDFLAGS' => '-ObjC'
}
s.prepare_command = <<-EOF
# 业务Module
rm -rf Verify-SwiftOC3rd/Classes/Modules
mkdir Verify-SwiftOC3rd/Classes/Modules
touch Verify-SwiftOC3rd/Classes/Modules/module.modulemap
cat <<-EOF > Verify-SwiftOC3rd/Classes/Modules/module.modulemap
framework module Verify {
umbrella header "Verify_SwiftOC3rd.h"
export *
link "sqlite3.0"
link "stdc++.6.0.9"
}
\EOF
# 创建Base Module
rm -rf Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Modules
mkdir Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Modules
touch Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Modules/module.modulemap
cat <<-EOF > Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Base.framework/Modules/module.modulemap
framework module BaiduMapAPI_Base {
umbrella header "BMKBaseComponent.h"
export *
link "sqlite3.0"
link "stdc++.6.0.9"
}
\EOF
# 创建Map Module
rm -rf Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Modules
mkdir Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Modules
touch Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Modules/module.modulemap
cat <<-EOF > Verify-SwiftOC3rd/Vendors/BaiduMapAPI_Map.framework/Modules/module.modulemap
framework module BaiduMapAPI_Map {
umbrella header "BMKMapComponent.h"
export *
link "sqlite3.0"
link "stdc++.6.0.9"
}
\EOF
EOF
end
运行结果如下:
我将代码上传到了Verify-SwiftOC3rd,欢迎指正
更多详情可以参考我写的一个框架,里面就包含了上述介绍的应用:SwiftX 针对微信,微博,JPush,网络,缓存,常用view,常用Extension,Json数据解析的封装