为什么在使用Swift Cocoa App和桥接头文件时会出现未声明类型'PubNub'的编译器错误?

12

我正在开始一个新的Cocoa Swift项目,通过以下Podfile将PubNub SDK纳入其中:

target 'myProject' do
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
pod 'PubNub', '~>4.0'
pod 'Alamofire', '~> 1.3'
end
target 'myProjectTests' do
end

在我的自动生成的桥接头文件中,我有PubNub的导入:

#import <PubNub/PubNub.h>

我的AppDelegate.swift文件:

import Cocoa

@NSApplicationMain


class AppDelegate: NSObject, NSApplicationDelegate {

var client:PubNub?

   func applicationDidFinishLaunching(aNotification: NSNotification) {
    let config = PNConfiguration( publishKey: "Your_Pub_Key", subscribeKey:     "Your_Sub_Key")

    client = PubNub.clientWithConfiguration(config)

    client?.addListener(self)

    client?.subscribeToChannels(["Your_Channel"], withPresence: false)

    client?.publish("Swift + PubNub!", toChannel: "demo", compressed: false, withCompletion: nil)    }

func client(client: PubNub!, didReceiveMessage message: PNMessageResult!) {
    println(message)
}

func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
}


}

由于使用了未声明的类型PubNub,项目无法构建。我已经检查了构建设置,Swift编译器-代码生成部分显示它指向目标的桥接头文件(自动填充)。

使用Xcode 6.4和pods版本0.38.2


1
请联系support@pubnub.com,我们可以为您提供更直接的帮助解决此问题。 - gurooj
当人们发布的问题没有足够的信息来回答时,我更喜欢直接与他们交流。此外,这个Podfile没有遵循Cocoapods文档页面指定的语法。 - gurooj
啊,显然如果你包含"use_frameworks!",那么你就没问题了,尽管它没有被清楚地记录在文档中。http://www.innerexception.com/2015/05/cocoapods-useframeworks-means-bridging.html - gurooj
1个回答

15

导入外部框架时缺少桥接头文件

来自Apple开发者文档的直接说明:

您可以导入具有纯Objective-C代码库、纯Swift代码库或混合语言代码库的外部框架。[...] 您可以使用以下语法将框架导入到不同目标中的任何Swift文件中:

import FrameworkName

修复

添加import PubNub框架。

import UIKit
import PubNub

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var client:PubNub?
    // ...
}

通过单一的importPubNub就被声明了,在Xcode编辑器中自动完成,编译、链接、构建和运行。

逐步Swift框架教程

由于下面的许多评论都暗示了在使用外部框架时总是需要桥接头文件,这是错误的,因为现在在Podfile中使用use_frameworks!指令,所以这里提供一个纯Swift的解决方案。后面还有一个可以下载和体验的Xcode项目。

iOS开发者文库中明确记录在概念使用Swift与Cocoa和Objective-C、章节混合编程、部分同一项目中的Swift和Objective-C、段落导入外部框架中:

导入外部框架的过程是相同的,无论该框架是用单一语言编写的还是包含来自两种语言的文件。

Podfile

platform :ios, '8.0'
use_frameworks!

target 'SO-31642385' do
pod 'PubNub', '~>4.0'
pod 'Alamofire', '~> 1.3'
end

安装pods

] pod install

Downloading dependencies
Installing Alamofire (1.3.1)
Installing CocoaLumberjack (2.0.0)
Installing PubNub (4.0.4)
Generating Pods project
Integrating client project

Please close any current Xcode sessions and use `SO-31642385.xcworkspace` for this project from now on.

导入框架

import UIKit
import PubNub

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var client:PubNub?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions:
                         [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        self.client = PubNub()
        return true
    }
    // ...
}

► 您可以在GitHub上找到此解决方案,更多细节请参见Swift Recipes


1
如果你正确使用桥接头,那是不必要的。 - gurooj
请查看此项目:https://github.com/jzucker2/StackOverflowSwiftBridgingHeader/tree/master它不会import PubNub,因为它已经包含在桥接头文件中。如果您需要更多关于如何工作的信息,请随时参考苹果文档,总有更多可以学习的。 - gurooj
1
在这个桥接头文件中列出的任何公共Objective-C头文件都将对Swift可见。Objective-C功能将自动在该目标中的任何Swift文件中可用,无需任何导入语句。使用与系统类相同的Swift语法使用您的自定义Objective-C代码。 - gurooj
@gurooj - 请考虑将您的评论发布为答案,这样我们就可以点赞或Jim Hankins可以接受为答案。 - Craig Conover
2
这是相反的情况。如果正确使用框架,Bridging Headers 就不再必要了。Pubnub 是一个框架。它已经包含在 use_frameworks! 中。只需添加 import PubNub 并完全绕过桥接机制即可。 - SwiftArchitect

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接