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.