将 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 上的应用程序获取源代码