stringByAppendingPathComponent ist nicht verfügbar

132

Meine App teilt ein Foto auf Instagram. Dazu speichert sie es zunächst in einem temporären Verzeichnis:

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

Es hat gearbeitet Swift 1.2, funktioniert aber nicht Swift 2.0.

Die angegebene Fehlermeldung lautet:

stringByAppendingPathComponent ist nicht verfügbar: Verwenden Sie stattdessen URLByAppendingPathComponent für NSURL.

Maysam
quelle

Antworten:

145

Es sieht so aus, als ob die Methode stringByAppendingPathComponentin Swift 2.0 entfernt wurde. Die Fehlermeldung schlägt also Folgendes vor:

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

Aktualisieren:

URLByAppendingPathComponent()wurde ersetzt durch appendingPathComponent()so stattdessen tun:

let writePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("instagram.igo")
Dániel Nagy
quelle
Wenn Sie dieses Design verwenden, werden Sie Probleme haben, wie Speicherplatz in% 20 umzuwandelnApplication%20Support
Roman
Nein, Swift 2.0 kann verwenden stringByAppendingPathComponent, siehe meine Antwort unten.
Jeffrey Neo
2
@ JeffreyNeo ja, aber das ist keine NSURLMethode, sondern eineNSString
Dániel Nagy
@ DánielNagy Ich meine, Sie sagten, " stringByAppendingPathComponentwird in Swift 2.0 entfernt" ist nicht korrekt, und @Maysam hat nicht nur nach der NSURLMethode gefragt .
Jeffrey Neo
4
@JeffreyNeo ist eigentlich richtig, da String in Swift 1.2 eine Methode namens stringByAppendingPathComponent hatte, Swift 2.0 jedoch nicht. Und NSString ist nicht Teil der Swift-Sprache, sondern Teil des Foundation-Frameworks.
Dániel Nagy
75

Es funktioniert für, NSStringso dass Sie es wie folgt verwenden können:

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

Jetzt können Sie diese Erweiterung verwenden , die Ihre konvertieren Stringzu NSStringersten und dann den Betrieb durchzuführen.

Und Ihr Code lautet:

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

Hier sind einige andere Methoden zur Verwendung:

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

Referenz von HIER .

Für schnelles 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
quelle
12
Dies ist zwar eine gültige Lösung, aber es gibt einen Grund, warum Apple diese Methoden entfernt hat. Die Verwendung von Pfaden zum Auffinden von Ressourcen ist veraltet und NSURLsollte stattdessen verwendet werden. Nur sagen.
Charlie Monroe
Snippet: String (NSString (String: Pfad) .stringByAppendingPathComponent (imageName)) ... ansonsten ganz einverstanden mit @CharlieMonroe
Bobjt
1
@CharlieMonroe Wenn das wirklich der Fall ist, warum gibt es im SDK immer noch eine Reihe von Methoden, die keine URL als Pfad akzeptieren?
Joris Mans
@JorisMans Dies sind normalerweise ältere Methoden (verfügbar seit 10.0 oder früh danach). Seit Einführung des Sandboxing gibt es keine Möglichkeit, einen Pfad mit z. B. einem Appscope-Lesezeichen weiterzugeben. Stattdessen benötigen Sie eine URL. Apple aktualisiert APIs, die nur wenige Benutzer verwenden, nur langsam. Oder haben Sie ein Beispiel für eine kürzlich hinzugefügte API (die letzten 3-4 Jahre)?
Charlie Monroe
1
@IulianOnofrei - Weil Sie stattdessen checkResourceIsReachable()oder checkPromisedItemIsReachable()auf URLverwenden sollten. FileManagerist immer noch eine ObjC-Klasse, NSFileManagerderen NSPräfix für Swift entfernt wurde und die fileExistsAtPathseit OS X 10.0 vorhanden war. Die Welt hat sich seitdem weiterentwickelt. Da Apps in einer Sandbox gespeichert sind (was unter iOS weniger offensichtlich ist), ist die Datei möglicherweise vorhanden. Sie haben möglicherweise keine Berechtigung zum Anzeigen. Die Datei befindet sich möglicherweise auch in der Cloud usw. Aus diesem Grund wird die einfache BOOLMethode durch etwas Komplexeres ersetzt URL, das jedoch semantisch korrekter ist.
Charlie Monroe
30

Wickeln Sie einfach Ihre Schnur als NSString.

let writePath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("instagram.igo")
Jeffrey Neo
quelle
Coole .. StringKlasse haben das nicht, aber es NSStringgibt sie! macht Sinn.
Preetam
16

für Swift 3 :

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

oder besser diese Erweiterung erstellen:

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

Verwendung:

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

Swift 3 Lösung:

Hier ist eine Funktion zum Abrufen des Dokumentenverzeichnispfads.

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

Wie benutzt man:

    getDocumentsDirectory.appendingPathComponent("google.com")

Ergebnis:

    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
quelle
5

Für schnelle 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
quelle
2

Sie können stattdessen URLByAppendingPathComponent () verwenden. Bitte beachten Sie, dass Sie die Pfadzeichenfolge kürzen sollten, um das Präfix „file: //“ zu entfernen:

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
quelle
0

Mach Folgendes:

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

Ich habe es versucht und es hat das Problem gelöst.

Vor:

let localPath = documentDirectory.URLByAppendingPathComponent(imageName)

nach dem:

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

Wenn die Verwendung von NSStringPfadmethoden (anstelle von StringURL-Methoden) akzeptabel ist, ist es viel einfacher, sie Stringmit einer berechneten Eigenschaft oder einer Methode zu erweitern, die ihren Wert als NSStringzurückgibt (anstatt die gewünschten Methoden in StringErweiterung zu duplizieren ):

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

und dann:

swiftStringPath.ns.appendingPathComponent("whateva")
swiftStringPath.ns.deletingPathExtension
Russisch
quelle
-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
quelle