stringByAppendingPathComponent non è disponibile


132

La mia app condivide foto su Instagram, per fare ciò prima salva su una directory temporanea:

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

Stava funzionando Swift 1.2, ma non funziona Swift 2.0.

Il messaggio di errore fornito è:

stringByAppendingPathComponent non è disponibile: utilizzare invece URLByAppendingPathComponent su NSURL.

Risposte:


145

Sembra che il metodo stringByAppendingPathComponentsia stato rimosso in Swift 2.0, quindi ciò che il messaggio di errore suggerisce è di usare:

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

Aggiornare:

URLByAppendingPathComponent()è stato sostituito da appendingPathComponent()così invece fai:

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

se hai intenzione di utilizzare questo design, avrai problemi come convertire lo spazio in% 20Application%20Support
Roman

no, Swift 2.0 può usare stringByAppendingPathComponent, vedi la mia risposta qui sotto.
Jeffrey Neo,

2
@JeffreyNeo sì, ma questo non è un NSURLmetodo ma unNSString
Dániel Nagy,

@ DánielNagy Intendo dire che " stringByAppendingPathComponentè stato rimosso in Swift 2.0" non è corretto e @Maysam non ha richiesto solo il NSURLmetodo.
Jeffrey Neo,

4
@JeffreyNeo in realtà, è corretto, dato che nella stringa di Swift 1.2 aveva un metodo chiamato stringByAppendingPathComponent, ma la stringa di Swift 2.0 no. E NSString non fa parte del linguaggio Swift, fa parte del framework Foundation.
Dániel Nagy,

75

Funziona NSStringquindi puoi usarlo in questo modo:

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

Ora è possibile utilizzare questa estensione, che permette di convertire la vostra Stringper NSStringprima e quindi eseguire l'operazione.

E il tuo codice sarà:

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

Ecco alcuni altri metodi per l'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)  
    }  
}

Riferimento da QUI .

Per 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
Sebbene questa sia una soluzione valida, c'è un motivo per cui Apple ha rimosso quei metodi: l'utilizzo dei percorsi per individuare le risorse è deprecato e si NSURLdovrebbero usare invece s. Sto solo dicendo.
Charlie Monroe,

snippet: String (NSString (string: path) .stringByAppendingPathComponent (imageName)) ... altrimenti, abbastanza d'accordo con @CharlieMonroe
Bobjt

1
@CharlieMonroe se è davvero così, perché ci sono ancora molti metodi che non accettano un URL come percorso, nell'SDK?
Joris Mans

@JorisMans In genere si tratta di metodi meno recenti (disponibili dalla 10.0 in poi). Da quando è stato introdotto il sandboxing, non c'è modo di passare un percorso con ad esempio il segnalibro di appscope - è invece necessario un URL. Apple è lento nell'aggiornamento delle API utilizzate solo da poche persone. Oppure hai un esempio di un'API aggiunta di recente (gli ultimi 3-4 anni)?
Charlie Monroe,

1
@IulianOnofrei - Perché dovresti usare checkResourceIsReachable()o checkPromisedItemIsReachable()su URLinvece. FileManagerè ancora una classe ObjC NSFileManagercon il NSprefisso rimosso per Swift ed fileExistsAtPathera presente da OS X 10.0. Il mondo si è evoluto da quando e poiché le app sono in modalità sandbox (che è meno ovvio su iOS), il file potrebbe esistere, potresti non avere il permesso di visualizzarlo; inoltre, il file può essere nel cloud, ecc. Ecco perché il BOOLmetodo semplice viene sostituito con qualcosa di più complesso URL, ma più semanticamente corretto.
Charlie Monroe,

30

Avvolgi semplicemente la stringa come NSString.

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

una bella .. Stringclasse non ce l'hanno ma NSStringesiste! ha senso.
preetam

16

per Swift 3 :

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

o meglio creare questa estensione:

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

utilizzo:

 let writePath = NSTemporaryDirectory().appendingPathComponent(directoryname)

6

Soluzione Swift 3:

Ecco una funzione per ottenere il percorso della directory dei documenti-

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

Come usare:

    getDocumentsDirectory.appendingPathComponent("google.com")

Risultato:

    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

Per 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

}

2

Puoi invece usare URLByAppendingPathComponent (). Si noti che è necessario tagliare la stringa del percorso per rimuovere il prefisso "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

Eseguire le seguenti operazioni:

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

0

Ho provato questo e ha risolto il problema.

prima:

let localPath = documentDirectory.URLByAppendingPathComponent(imageName)

dopo:

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

-1

Se l'utilizzo di NSStringmetodi path (anziché Stringmetodi URL) è accettabile, è molto più facile estenderlo Stringcon una proprietà calcolata o un metodo che restituisce il suo valore come NSString(invece di duplicare i metodi desiderati Stringnell'estensione):

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

e poi:

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

-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)
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.