将 swift 2.3 转换为 swift 3 错误

Posted

技术标签:

【中文标题】将 swift 2.3 转换为 swift 3 错误【英文标题】:Convert swift 2.3 to swift 3 error 【发布时间】:2016-12-18 15:09:46 【问题描述】:

我在 xcode 8.2 中将 swift 2.3 转换为 swift 3

swift 2.3:有代码,有代码,有代码,有代码,有代码

func playAudio() 
    self.stopAudio()
    let lessonObject:LessonObject = self.lessonArray[self.selectedIndex] as! LessonObject
    let fullPath:String! = Constants.URL_HOST + "\(lessonObject.lessonPath)"
    let soundURL:NSURL! = NSURL.init(string:fullPath)
    let documentsDirectoryURL =  NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
    let destinationUrl = documentsDirectoryURL.URLByAppendingPathComponent(soundURL.lastPathComponent!)
    if NSFileManager().fileExistsAtPath(destinationUrl!.path!) 
        if let soundData = NSData(contentsOfFile: destinationUrl!.path!) 
            self.initAudioWithData(soundData)
        
        else 
            self.audioErrorAction()
        
        return
    
    
    if let soundData = NSData(contentsOfURL:NSURL(string:fullPath)!) 
        self.initAudioWithData(soundData)
    
    else 
        self.audioErrorAction()
    

swift 3:代码有错误吗?

        func playAudio() 
        self.stopAudio()
        let lessonObject:LessonObject = self.lessonArray[self.selectedIndex] as! LessonObject
        let fullPath:String! = Constants.URL_HOST + "\(lessonObject.lessonPath)"
let soundURL:URL! = URL.init(fileURLWithPath: fullPath)
        let documentsDirectoryURL =  FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationUrl = documentsDirectoryURL.appendingPathComponent(soundURL.lastPathComponent)
        if FileManager().fileExists(atPath: destinationUrl.path)
            if let soundData = try? Data(contentsOf: URL(fileURLWithPath: destinationUrl.path))
            
                self.initAudioWithData(soundData)
            
            else 
                self.audioErrorAction()
            
            return
        
if let soundData = try? Data(contentsOf: URL(string:fullPath)!)
        
            self.initAudioWithData(soundData)
        
        else 
            self.audioErrorAction()
        
    

转换我的错误后:

在展开可选值时发现 nil。

我构建了 swift 2.3:destinationUrl = "file:///Users/admin/Library/.../Documents/test.mp3" 0x00006080002a73e0

我构建了 swift 3:destinationUrl = "file:///Users/admin/Library/.../Documents/Optional(%22test.mp3%22)"

【问题讨论】:

哪一行报错? 如果让 soundData = 试试?数据(contentsOf:URL(字符串:fullPath)!) 如果您已经将destinationUrl 作为URL,为什么要从它的path 创建一个新的URL?只需if let soundData = try? Data(contentsOf: destinationUrl) 你不应该使用init(fileURLWithPath: String)吗?而不是init(string: String)? 无论如何,如果文件不存在,你为什么要加载数据? 【参考方案1】:

错误的来源在这一行

let fullPath:String! = Constants.URL_HOST + "\(lessonObject.lessonPath)"

首先——不管与问题无关——不要注释编译器可以推断的类型。你把一个 good 非可选字符串变成了一个 worse 隐式展开的可选字符串。

lessonPath 属性显然也是一个(隐式展开)可选。使用字符串插值,您会得到文字 "Optional(foo)"。如果属性可能是nil,则需要解开可选绑定或使用可选绑定。如果值永远不能是nil,请考虑使用非可选属性

let fullPath = Constants.URL_HOST + "\(lessonObject.lessonPath!)"

更多信息请阅读Swift 3 incorrect string interpolation with implicitly unwrapped Optionals

永远不要将属性声明为隐式展开的可选项 避免编写初始化程序

【讨论】:

以上是关于将 swift 2.3 转换为 swift 3 错误的主要内容,如果未能解决你的问题,请参考以下文章

从 Swift 2.3 -> 3.2 转换时,无法将 String 类型的值转换为指定类型 NSManagedObjectContext

从 swift 3 转换为 swift 2.3 或从 iPhone 上的应用程序获取源代码

转换为 swift 2.3 后模糊使用“下标”

转换为 swift 2.3 后模糊使用“下标”

如何在 Swift 2.3 中将 UInt8 转换为 Anyobject

升级到 Xcode 8 并将语法从 swift 2.3 转换为 swift 3.0 后文件丢失警告