stringByAppendingPathComponent no está disponible

132

Mi aplicación comparte una foto en Instagram, para hacer esto primero la guarda en un directorio temporal:

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

Estaba trabajando Swift 1.2, pero no funciona Swift 2.0.

El mensaje de error dado es:

stringByAppendingPathComponent no está disponible: use URLByAppendingPathComponent en NSURL en su lugar.

Maysam
fuente

Respuestas:

145

Parece que el método stringByAppendingPathComponentse elimina en Swift 2.0, por lo que lo que sugiere el mensaje de error es usar:

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

Actualizar:

URLByAppendingPathComponent()ha sido reemplazado por appendingPathComponent()lo que en su lugar:

let writePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("instagram.igo")
Dániel Nagy
fuente
si va a utilizar este diseño, tendrá problemas como convertir el espacio a% 20Application%20Support
Roman
no, Swift 2.0 puede usar stringByAppendingPathComponent, vea mi respuesta a continuación.
Jeffrey Neo
2
@JeffreyNeo sí, pero ese no es un NSURLmétodo sino unNSString
Dániel Nagy
@ DánielNagy Quiero decir que dijo que " stringByAppendingPathComponentse eliminó en Swift 2.0" no es correcto, y @Maysam no solicitó el único NSURLmétodo.
Jeffrey Neo
44
@JeffreyNeo en realidad, es correcto, ya que en Swift 1.2's String tenía un método llamado stringByAppendingPathComponent, pero Swift 2.0's String no. Y NSString no es parte del lenguaje Swift, es parte del marco de la Fundación.
Dániel Nagy
75

Está funcionando para NSStringque pueda usarlo así:

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

Ahora puede usar esta extensión que convertirá su Stringa NSStringprimero y luego realizará la operación.

Y tu código será:

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

Aquí hay algunos otros métodos de uso:

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

Referencia desde AQUÍ .

Para 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)
    }
}
Dharmesh Kheni
fuente
12
Si bien esta es una solución válida, hay una razón por la cual Apple ha eliminado esos métodos: el uso de rutas para localizar recursos está en desuso y se NSURLdeben usar s en su lugar. Solo digo.
Charlie Monroe
fragmento: Cadena (NSString (cadena: ruta) .stringByAppendingPathComponent (imageName)) ... de lo contrario, muy de acuerdo con @CharlieMonroe
Bobjt
1
@CharlieMonroe, si ese es realmente el caso, ¿por qué todavía hay un montón de métodos que no aceptan una URL como ruta, en el SDK?
Joris Mans
@JorisMans Suelen ser métodos más antiguos (disponibles desde 10.0 o poco después). Desde que se introdujo el sandboxing, no hay forma de pasar por una ruta con, por ejemplo, el marcador de aplicacionescope; en su lugar, necesita una URL. Apple tarda en actualizar las API que solo usan unas pocas personas. ¿O tiene un ejemplo de una API recientemente agregada (los últimos 3-4 años)?
Charlie Monroe
1
@IulianOnofrei - Porque deberías estar usando checkResourceIsReachable()o checkPromisedItemIsReachable()en su URLlugar. FileManagersigue siendo una clase ObjC NSFileManagercon el NSprefijo eliminado para Swift y fileExistsAtPathestuvo allí desde OS X 10.0. El mundo ha evolucionado desde entonces y, dado que las aplicaciones están protegidas (lo que es menos obvio en iOS), el archivo puede existir, es posible que no tenga permiso para verlo; también, el archivo puede estar en la nube, etc. Es por eso que el BOOLmétodo simple se reemplaza por algo más complejo URLpero más semánticamente correcto.
Charlie Monroe
30

Simplemente envuelva su cadena como NSString.

let writePath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("instagram.igo")
Jeffrey Neo
fuente
genial ... la Stringclase no tiene esto pero NSStringexiste! tiene sentido.
antes del
16

para Swift 3 :

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

o mejor cree esta extensión:

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

uso:

 let writePath = NSTemporaryDirectory().appendingPathComponent(directoryname)
Vyacheslav
fuente
6

Solución Swift 3:

Aquí hay una función para obtener la ruta del directorio de documentos

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

Cómo utilizar:

    getDocumentsDirectory.appendingPathComponent("google.com")

Resultado:

    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
Revanth
fuente
5

Para 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

}
Mehul Chuahan
fuente
2

En su lugar, puede usar URLByAppendingPathComponent (). Tenga en cuenta que debe recortar la cadena de ruta para eliminar el prefijo "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
}
user2374993 - Inbal Tish
fuente
0

Haz lo siguiente:

(("\(fileName)" as NSString).lastPathComponent as NSString).stringByDeletingPathExtension
Mauro Delazeri
fuente
0

Intenté esto y resolvió el problema.

antes de:

let localPath = documentDirectory.URLByAppendingPathComponent(imageName)

después:

let localPath = (documentDirectory as NSString).appendingPathComponent(imageName)
Miah G.
fuente
-1

Si usar NSStringmétodos de ruta (en lugar de Stringmétodos URL) es aceptable, es mucho más fácil extenderlo Stringcon una propiedad calculada o un método que devuelva su valor como NSString(en lugar de duplicar los métodos deseados en Stringextensión):

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

y entonces:

swiftStringPath.ns.appendingPathComponent("whateva")
swiftStringPath.ns.deletingPathExtension
ruso
fuente
-2

Swift 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)
    }
}
Duncan Groenewald
fuente