stringByAppendingPathComponent不可用


132

我的应用程序在Instagram上共享照片,为此,首先将其保存在一个临时目录中:

let writePath = NSTemporaryDirectory().stringByAppendingPathComponent("instagram.igo")

它正在工作Swift 1.2,但不起作用Swift 2.0

给定的错误消息是:

stringByAppendingPathComponent不可用:在NSURL上使用URLByAppendingPathComponent。

Answers:


145

看来该方法stringByAppendingPathComponent已在Swift 2.0中删除,因此错误消息建议使用:

let writePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("instagram.igo")

更新:

URLByAppendingPathComponent()已被替换为appendingPathComponent()

let writePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("instagram.igo")

如果要使用此设计,将遇到诸如将空间转换为%20的问题Application%20Support
Roman Roman

不,Swift 2.0可以使用stringByAppendingPathComponent,请参阅下面的答案。
Jeffrey Neo

2
@JeffreyNeo是的,但不是一个NSURL方法,而是一个NSString
丹尼尔·纳吉

@DánielNagy我的意思是您说“ stringByAppendingPathComponent在Swift 2.0中被删除”是不正确的,并且@Maysam并没有要求仅提供NSURL方法。
Jeffrey Neo

4
@JeffreyNeo实际上是正确的,因为在Swift 1.2的String中有一个名为stringByAppendingPathComponent的方法,但是Swift 2.0的String没有。NSString不是Swift语言的一部分,它是Foundation框架的一部分。
丹尼尔·纳吉

75

它正在工作,NSString因此您可以像这样使用它:

extension String {
    func stringByAppendingPathComponent(path: String) -> String {
        let nsSt = self as NSString
        return nsSt.stringByAppendingPathComponent(path)
    }
}

现在,您可以使用此扩展名,该扩展名将首先转换StringNSString,然后再执行操作。

您的代码将是:

let writePath = NSTemporaryDirectory().stringByAppendingPathComponent("instagram.igo")

这是其他一些使用方法:

extension String {  

    var lastPathComponent: String {  
        return (self as NSString).lastPathComponent  
    }  
    var pathExtension: String {  
        return (self as NSString).pathExtension  
    }  
    var stringByDeletingLastPathComponent: String {  
        return (self as NSString).stringByDeletingLastPathComponent  
    }  
    var stringByDeletingPathExtension: String {  
        return (self as NSString).stringByDeletingPathExtension  
    }  
    var pathComponents: [String] {  
        return (self as NSString).pathComponents  
    }  
    func stringByAppendingPathComponent(path: String) -> String {  
        let nsSt = self as NSString  
        return nsSt.stringByAppendingPathComponent(path)  
    }  
    func stringByAppendingPathExtension(ext: String) -> String? {  
        let nsSt = self as NSString  
        return nsSt.stringByAppendingPathExtension(ext)  
    }  
}

参考从这里

对于Swift 3.0:

extension String {
    func stringByAppendingPathComponent1(path: String) -> String {
        let nsSt = self as NSString
        return nsSt.appendingPathComponent(path)
    }
}

let writePath = NSTemporaryDirectory().stringByAppendingPathComponent(path: "instagram.igo")


extension String {

    var lastPathComponent: String {
        return (self as NSString).lastPathComponent
    }
    var pathExtension: String {
        return (self as NSString).pathExtension
    }
    var stringByDeletingLastPathComponent: String {
        return (self as NSString).deletingLastPathComponent
    }
    var stringByDeletingPathExtension: String {
        return (self as NSString).deletingPathExtension
    }
    var pathComponents: [String] {
        return (self as NSString).pathComponents
    }
    func stringByAppendingPathComponent(path: String) -> String {
        let nsSt = self as NSString
        return nsSt.appendingPathComponent(path)
    }
    func stringByAppendingPathExtension(ext: String) -> String? {
        let nsSt = self as NSString
        return nsSt.appendingPathExtension(ext)
    }
}

12
尽管这是一个有效的解决方案,但是Apple删除了这些方法是有原因的-不建议使用NSURLs 来查找资源的路径,而应使用s。只是说。
查理·梦露

片段:String(NSString(string:path).stringByAppendingPathComponent(imageName))...否则,我非常同意@CharlieMonroe
Bobjt

1
如果确实是@CharlieMonroe,为什么在SDK中仍然有很多方法不接受URL作为路径?
Joris Mans

@JorisMans这些通常是较旧的方法(自10.0或之后开始可用)。自从引入沙箱以来,就无法通过诸如appscope书签的路径传递-您需要使用URL。苹果公司在更新只有少数人使用的API方面进展缓慢。还是您有一个最近添加的API(过去3-4年)的示例?
查理·梦露

1
@IulianOnofrei -因为你应该使用checkResourceIsReachable()checkPromisedItemIsReachable()URL代替。FileManager仍然是一个ObjC类NSFileManagerNS为Swift删除了前缀,并且fileExistsAtPath从OS X 10.0开始就存在。此后世界已经发生了变化,并且随着应用被沙盒化(在iOS上不太明显),该文件可能存在,您可能没有查看权限。文件也可能在云中等。这就是为什么将简单BOOL方法替换为的更复杂URL但语义更正确的原因。
查理·梦露

30

只需将字符串包装为即可NSString

let writePath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("instagram.igo")

很酷的一个.. Stringclass没有这个,但是NSString存在!说得通。
preetam '16

16

对于Swift 3

let writePath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(directoryname).path

或更好地创建此扩展:

extension String {
    func appendingPathComponent(_ string: String) -> String {
        return URL(fileURLWithPath: self).appendingPathComponent(string).path
    }
}

用法:

 let writePath = NSTemporaryDirectory().appendingPathComponent(directoryname)

6

Swift 3解决方案:

这是获取文档目录路径的功能-

    func getDocumentsDirectory() -> URL {
         let paths = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask)
         let documentsDirectory = paths[0]
         return documentsDirectory
     }

如何使用:

    getDocumentsDirectory.appendingPathComponent("google.com")

结果:

    file:///var/folders/w1/3rcp2fvs1qv43hfsh5876s0h0000gn/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.MyPlayground-7CF9F706-509C-4D4C-997E-AB8FE9E4A6EA/Documents/google.com

5

快速2.0

// Get the documents Directory
    func documentsDirectory() -> String {
        let documentsFolderPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]
        return documentsFolderPath
    }

// Get path for a file in the directory
func fileInDocumentsDirectory(filename: String) -> String {

    let writePath = (documentsDirectory() as NSString).stringByAppendingPathComponent("Mobile")

    if (!NSFileManager.defaultManager().fileExistsAtPath(writePath)) {
        do {
            try NSFileManager.defaultManager().createDirectoryAtPath(writePath, withIntermediateDirectories: false, attributes: nil) }
            catch let error as NSError {
                print(error.localizedDescription);
        }
    }
    return (writePath as NSString).stringByAppendingPathComponent(filename)
}

//# MARK: - Save Image in Doc dir
func saveImage (image: UIImage, path: String ) -> Bool{

    let pngImageData = UIImagePNGRepresentation(image)
    //        let jpgImageData = UIImageJPEGRepresentation(image, 1.0)   // if you want to save as JPEG
    let result = pngImageData!.writeToFile(path, atomically: true)

    print("\(result)")
    print("\(path)")

    return result

}

2

您可以改用URLByAppendingPathComponent()。请注意,您应该修剪路径字符串以删除“ file://”前缀:

let uniqueFileName = NSUUID().UUIDString
let documentsDirectory = getDocumentsDirectoryURL()
    if let path = documentsDirectory?.URLByAppendingPathComponent(uniqueFileName) {
        var pathString = path.absoluteString
        pathString = imagePathString.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "file://"))
}

func getDocumentsDirectoryURL() -> NSURL? {
    let fileManager = NSFileManager()
    if let docsDirectory = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first {
        return docsDirectory
    }
    return nil
}


0

我尝试了一下,它解决了问题。

之前:

let localPath = documentDirectory.URLByAppendingPathComponent(imageName)

后:

let localPath = (documentDirectory as NSString).appendingPathComponent(imageName)

-1

如果可以接受使用NSString路径方法(而非StringURL方法),则String使用计算属性或返回其值的方法进行扩展要容易得多NSString(而不是在String扩展名中复制所需的方法):

extension String
{
    var ns: NSString { return self as NSString }
}

然后:

swiftStringPath.ns.appendingPathComponent("whateva")
swiftStringPath.ns.deletingPathExtension

-2

斯威夫特4

extension String {

    var lastPathComponent: String {
        return (self as NSString).lastPathComponent
    }
    var pathExtension: String {
        return (self as NSString).pathExtension
    }
    var stringByDeletingLastPathComponent: String {
        return (self as NSString).deletingLastPathComponent
    }
    var stringByDeletingPathExtension: String {
        return (self as NSString).deletingPathExtension
    }
    var pathComponents: [String] {
        return (self as NSString).pathComponents
    }
    func stringByAppendingPathComponent(path: String) -> String {
        let nsSt = self as NSString
        return nsSt.appendingPathComponent(path)
    }
    func stringByAppendingPathExtension(ext: String) -> String? {
        let nsSt = self as NSString
        return nsSt.appendingPathExtension(ext)
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.