【问题标题】:stringByAppendingPathComponent is unavailablestringByAppendingPathComponent 不可用
【发布时间】:2015-12-06 17:25:06
【问题描述】:

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

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

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

给出的错误信息是:

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

【问题讨论】:

    标签: ios swift swift2


    【解决方案1】:

    看起来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
    • 不,Swift 2.0 可以使用stringByAppendingPathComponent,请看下面我的回答。
    • @JeffreyNeo 是的,但这不是NSURL 方法,而是NSString
    • @DánielNagy 我的意思是你说“stringByAppendingPathComponent 在 Swift 2.0 中被删除”是不正确的,@Maysam 并没有只要求 NSURL 方法。
    • @JeffreyNeo 实际上是正确的,因为在 Swift 1.2 的 String 中有一个名为 stringByAppendingPathComponent 的方法,但 Swift 2.0 的 String 没有。而且 NSString 不是 Swift 语言的一部分,它是 Foundation 框架的一部分。
    【解决方案2】:

    它适用于NSString,因此您可以像这样使用它:

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

    现在您可以使用此扩展程序将您的String 转换为NSString,然后执行操作。

    您的代码将是:

    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)  
        }  
    }
    

    来自HERE的参考。

    对于 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)
        }
    }
    

    【讨论】:

    • 虽然这是一个有效的解决方案,但 Apple 删除这些方法是有原因的 - 不推荐使用路径来定位资源,而应使用 NSURLs。只是说。
    • sn-p: String( NSString( string: path ).stringByAppendingPathComponent( imageName ) ) ... 否则,完全同意@CharlieMonroe
    • @CharlieMonroe 如果真的是这样,为什么 SDK 中还有一堆不接受 URL 作为路径的方法?
    • @JorisMans 这些通常是较旧的方法(自 10.0 或之后的早期可用)。自从引入沙盒以来,就没有办法通过例如路径传递。 appscope 书签 - 您需要一个 URL。 Apple 在更新只有少数人使用的 API 方面很慢。或者您有最近添加的 API 的示例(过去 3-4 年)?
    • @IulianOnofrei - 因为您应该在 URL 上使用 checkResourceIsReachable()checkPromisedItemIsReachable()FileManager 仍然是一个 ObjC 类 NSFileManager,为 Swift 删除了 NS 前缀,fileExistsAtPath 从 OS X 10.0 开始就一直存在。自从应用程序被沙盒化(这在 iOS 上不太明显)以来,世界已经发展,文件可能存在,您可能没有查看它的权限;此外,文件可能在云中等。这就是为什么简单的BOOL 方法被替换为更复杂的URL 方法,但在语义上更正确。
    【解决方案3】:

    只需将您的字符串包装为NSString

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

    【讨论】:

    • 很酷的一个.. String 类没有这个但 NSString 存在!有道理。
    【解决方案4】:

    对于 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)
    

    【讨论】:

      【解决方案5】:

      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
      

      【讨论】:

        【解决方案6】:

        对于 swift 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
        
        }
        

        【讨论】:

          【解决方案7】:

          您可以改用 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
          }
          

          【讨论】:

            【解决方案8】:

            执行以下操作:

            (("\(fileName)" as NSString).lastPathComponent as NSString).stringByDeletingPathExtension
            

            【讨论】:

              【解决方案9】:

              我试过了,它解决了这个问题。

              之前:

              let localPath = documentDirectory.URLByAppendingPathComponent(imageName)
              

              之后:

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

              【讨论】:

                【解决方案10】:

                如果使用NSString 路径方法(而不是String URL 方法)是可以接受的,那么使用计算属性或将其值返回为NSString 的方法扩展String 会容易得多(而不是复制所需的String 扩展中的方法):

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

                然后:

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

                【讨论】:

                  【解决方案11】:

                  斯威夫特 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)
                      }
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 2015-11-14
                    • 1970-01-01
                    • 2011-06-25
                    • 2015-11-26
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多