【问题标题】:Alamofire NSURLRequest Ambiguous use of URLStringAlamofire NSURLRequest 模糊使用 URLString
【发布时间】:2015-05-20 14:02:08
【问题描述】:

所以我对 swift 比较陌生,最近我开始了一个新项目,该项目需要对远程服务器上的 JSON api 进行多个网络请求,所以我决定按照这些教程使用 Alamofire 库(通过 cocoapods 包含的 1.1 版):

http://www.raywenderlich.com/85080/beginning-alamofire-tutorial http://www.raywenderlich.com/87595/intermediate-alamofire-tutorial

以防万一,这是我在 podfile 中用于包含 Alamofire 库的代码:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

pod 'Alamofire', '~> 1.1'

一个要求是需要为特定的 tableview 下载和缓存图像。按照教程,我构建了框架提供的 Alamofire.Request 类的扩展:

extension Alamofire.Request {

    class func imageResponseSerializer() -> Serializer {
        return { request, response, data in
            if data == nil {
                return (nil, nil)
            }

            let image = UIImage(data: data!, scale: UIScreen.mainScreen().scale)

            return (image, nil)
        }
    }

    func responseImage(completionHandler: (NSURLRequest, NSHTTPURLResponse?, UIImage?, NSError?) -> Void) -> Self {
        return response(serializer: Request.imageResponseSerializer(), completionHandler: { (request, response, image, error) in
            completionHandler(request, response, image as? UIImage, error)
        })
    }

}

有了这个我请求的图像

Alamofire.Request(.GET, "IMAGE URL").responseImage(){
     (request, _, image, error) in

     // Logic used to display image and save it to the cache

}

在没有缓存的情况下测试下载表明它可以工作并且我可以显示它们,但是当我需要原始 URL 作为我的 NSCache 的键时出现问题,但每次我尝试访问属性 (request.URLString) ,xcode总是会抛出很多错误。

尝试像这样访问该属性:

self.imageCache.setObject(image!, forKey: request.URLString)

在编辑器中抛出“Ambiguous use of URLString”,并试图将其与其他字符串值进行比较总是会抛出一个错误,提示“Cannot invoke 'operand' with an argument list of type '($T6??, String)' "

** 注意$T6中的数字??取决于我在哪里使用它

我尝试搜索对此类错误的引用,但我发现的所有内容都与选项的工作方式有关(不知道这是否是这里的问题,但它们都没有工作),所以如果有人知道这个问题的解决方案错误,我将不胜感激。

编辑

这是我使用它的完整功能(在出现错误的行中注释)

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        // Current Cell
        let cell = self.table.dequeueReusableCellWithIdentifier("entry_cell", forIndexPath: indexPath) as EntryTableViewCell

        // Current entry
        let entry = entries[indexPath.row]

        // Date Formatter
        var formatter = NSDateFormatter()
        formatter.dateStyle = NSDateFormatterStyle.LongStyle

        cell.entryTitle.text        = entry.title!
        cell.entryContent.text      = entry.content!
        cell.entryDateLabel.text    = formatter.stringFromDate(entry.createdAt!)

        // Try to download image
        let imageURL = ApplicationPreferences.resourcesURLPrefix + entry.picture!

        // 1
        if cell.request?.request.URLString != imageURL { // Error: cannot invoke '!=' with an argument list of type '($T6??, String)'
            cell.request?.cancel()
        }

        // 2
        if let image = self.imageCache.objectForKey(imageURL) as? UIImage {
            cell.entryImageView.image = image
        } else {
            // 3
            cell.entryImageView.image = nil

            // 4
            cell.request = Alamofire.request(.GET, imageURL).validate(contentType: ["image/*"]).responseImage() {
                (request, _, image, error) in

                if error == nil && image != nil {
                    // 5
                    self.imageCache.setObject(image!, forKey: request.URLString) // Error: Ambiguous use of 'URLString'

                    // 6
                    if request.URLString == cell.request?.request.URLString { // Error: Cannot invoke '==' with an argumet list of type '($T2??, $T8??)'
                        cell.entryImageView.image = image
                    }
                } else {
                    /*
                    If the cell went off-screen before the image was downloaded, we cancel it and
                    an NSURLErrorDomain (-999: cancelled) is returned. This is a normal behavior.
                    */
                }
            }
        }
        return cell

    }

以防万一,该 UITableViewCell 子类的来源是:

import UIKit
import Alamofire

class EntryTableViewCell: UITableViewCell {

    @IBOutlet weak var entryImageView: UIImageView!
    @IBOutlet weak var entryTitle: UILabel!
    @IBOutlet weak var entryContent: UILabel!
    @IBOutlet weak var entryDateBackgroundView: UIView!
    @IBOutlet weak var entryDateLabel: UILabel!

    var request: Alamofire.Request?

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

【问题讨论】:

  • NSCache/NSMutableDictionary 语法没有任何问题。我复制了你的扩展和代码 sn-p,它对我来说很好(Alamofire.Request(.GET, ...) 语法应该是 Alamofire.request(.GET, ...) 除外)。如果代码早期出现问题(缺少大括号等),通常会出现这些神秘的$T6 样式错误。但根据迄今为止提供的内容,无法确定这一点。
  • 奇怪的是,每次我尝试访问 URLString 变量时,我都会得到“URLString 错误的模糊使用”,无论我在代码中的什么位置使用它。另一件事是 response.URL 属性不会发生这种情况(不知道为什么)
  • 好吧,我刚刚拉了 Alamofire 并尝试了它,它工作正常。首先,当您遇到无法解释的行为时,有一个标准程序: (a) 退出 Xcode; (b) 清空派生数据文件夹; (c) 重新启动 Xcode。如果问题仍然存在,也许可以在某处上传可重现的问题示例,我们可以查看一下。
  • 再次,我使用了您更新的代码示例,它编译得很好。也许您可以将项目上传到某个地方,我们可以看看。

标签: ios swift nsurlrequest alamofire


【解决方案1】:

我猜您使用的是 Xcode 6.3b3...对吗?如果是……请继续阅读。如果没有,请对此答案发表评论,我会修改。

Xcode 6.2

您有两个地方(数字 1 和 6)将 URLStringURLString? 进行比较,这就是您收到编译器错误的原因。您需要在其上方进行可选绑定或手动展开,这在任何一种情况下都可能不是一个好主意。

仍然不能完全确定 5 号是否存在实际问题,或者它是否是 1 号和 6 号的副作用。

Xcode 6.3b3 和 Swift 1.2

在最新版本的 Swift 中,他们整理了一些模糊不清的地方,即当您有默认参数值时应该调用哪些函数。 Alamofire 有一些无效的函数调用,需要重构才能与 Swift 1.2 编译器的最新版本一起使用。您最可能需要做的是在 Alamofire 中注释掉以下行。

public func response(completionHandler: (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) -> Self {
    return response(Request.responseDataSerializer(), completionHandler: completionHandler)
}

这是一个(有几个)最有可能使您的图像序列化器绊倒的违规者。我明天很可能会为此推一个 PR。与此同时,我只是想我会为你指明正确的方向。

【讨论】:

  • 您好,感谢您的回复。我实际上使用的是 Xcode 6.2 和最新的稳定 swift 实现(你从 appstore 获得的那个),但我仍然尝试在 alamofire 源代码中评论该功能。我从位于 Pods 项目中的 Alamofire.swift 文件中删除了它,但它仍然给了我同样的错误。我将发布更多代码,看看它是否有助于澄清情况
  • 嗨@EricDS,我更新了我的答案,我想我可能已经找到了你的问题。
  • 谢谢@Rob,你在这两点上都是绝对正确的。我错过了他编辑中的更改,对于第一期和第二期,我认为他正在访问AnyObject? 返回数据。我将拉出我添加的部分。感谢您发现“我的”错误。
  • 您说“您正在将 URLStringURLString? 进行比较,这就是您收到编译器错误的原因”。真的吗?你试过吗?这对我来说可以。你试过编译这段代码吗?
  • 伙计,没有示例项目的男士们,我没有建议了:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-17
  • 1970-01-01
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多