iOS8: Custom Swift Framework accessing external fr

2020-03-02 05:02发布

问题:

I'm trying to create a custom framework called CouchbaseKit (a new target in Xcode) in Swift. Inside my CouchbaseKit, I need to access CouchBaseLite Framework that's entirely written in Obj-C. I'm using Cocoapods to manage CouchBaseLite and a couple of other frameworks. Below is my podfile.

Podfile

# Uncomment this line to define a global platform for your project
link_with ['CouchbaseKit']
# platform :ios, '8.0'

use_frameworks!
target 'CouchbaseDB' do
link_with ['CouchbaseKit']

pod 'couchbase-lite-ios'
pod 'SwiftyJSON', '~> 2.2.0'
pod 'Alamofire', '~> 1.2'
pod 'XCGLogger', '~> 2.0'
end

target 'CouchbaseDBTests' do
end

target 'CouchbaseKit' do
end

target 'CouchbaseKitTests' do
end

Pods inside the project:

For my TARGETS I have the following settings in Build Phases.

Define Module Yes

Allow Non-modular Includes in Framework Modules Yes

Problem: When I try to access the CouchbaseLite framework inside my CouchbaseKit (my custom framework), I get an error, "No such module 'CouchbaseLite' does not exist.

Tried:

  1. Since the project is in Swift, I created an Objective-C File and Hit yes to "Would you like to configure an Objective-C bridging header?"

  2. Even though Allow Non-modular Includes in Framework Modules is set to YES in all targets, I still get an error when I try to #import <CouchbaseLite/CouchbaseLite.h> in CouchbaseKit.h

Here is what my Build Phases looks like for my custom framework CouchbaseKit

Question: How can I see an external Objective-C framework (CouchasebaseLite) in my custom Swift framework?

回答1:

Unfortunately Cocoapods 0.39 suffers from "Transitive Vendor Dynamic Libraries Unsupported" You'll see this with the newest couchbase-lite-ios release including the binary CouchbaseLite.framework. This unfortunately issue bit me so hard I had to refactor everything to use Carthage, and manually manage my frameworks in my final projects.

Speaking of which the binary released CouchbaseLite.framework is simply missing a module map.

Add one to: CouchbaseLite.framework/Modules/module.modulemap

framework module CouchbaseLite {
  umbrella header "CouchbaseLite.h"

  export *
  module * { export * }
}

You will then be able to include this framework into a bridging header, and have your dynamic framework nest properly. But you might need to switch to building your CouchbaseKit.framework to using Carthage like I did.



回答2:

CouchbaseLite on iOS is a static framework, i.e. its binary is a static library not a dylib. This means it's linked into your app as though it were a source file. For this reason you don't use import in Swift to access it; the classes are already in the same namespace as your app's classes.



回答3:

If you still want to use Cocoapods you can follow this

Steps:

  • Create a folder called the name of your Framework you want to use in that case CouchbaseLite and inside it create module map. The file name will be module.map and its content will be

module CouchbaseLite { header "../Pods/couchbase-lite-ios/CouchbaseLite.framework/Headers/CouchbaseLite.h" export * }

Important Note: Don't add that folder to the project, I don't know why not when done it will not work.

  • Import Paths under Swift Compiler – Search Paths in your project settings. Use ${SRCROOT} in the module path (e.g. ${SRCROOT}/CouchbaseLite) .

  • Then you can import it like any swift module.

Update: It will work nicely in Xcode, but when I have tried to validate the pod with the pod lint it still give error and I still don't know why.