stringByAppendingPathComponent jest niedostępny

132

Moja aplikacja udostępnia zdjęcie na Instagramie, aby to zrobić, najpierw zapisuje je w katalogu tymczasowym:

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

Pracował Swift 1.2, ale nie działa Swift 2.0.

Podany komunikat o błędzie to:

stringByAppendingPathComponent jest niedostępny: zamiast tego użyj URLByAppendingPathComponent na NSURL.

Maysam
źródło

Odpowiedzi:

145

Wygląda na to, że metoda stringByAppendingPathComponentzostała usunięta w Swift 2.0, więc komunikat o błędzie sugeruje użycie:

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

Aktualizacja:

URLByAppendingPathComponent()został zastąpiony przez, appendingPathComponent()więc zamiast tego zrób:

let writePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("instagram.igo")
Dániel Nagy
źródło
jeśli zamierzasz użyć tego projektu, będziesz miał problemy, takie jak zamiana miejsca na% 20Application%20Support
Roman
nie, Swift 2.0 może używać stringByAppendingPathComponent, zobacz moją odpowiedź poniżej.
Jeffrey Neo
2
@JeffreyNeo tak, ale to nie jest NSURLmetoda, aleNSString
Dániel Nagy
@ DánielNagy Mam na myśli to, że powiedziałeś, że „ stringByAppendingPathComponentzostało usunięte w Swift 2.0” nie jest poprawne, a @Maysam nie pytał o jedyną NSURLmetodę.
Jeffrey Neo
4
@JeffreyNeo w rzeczywistości jest to poprawne, ponieważ String w Swift 1.2 miał metodę o nazwie stringByAppendingPathComponent, ale String w Swift 2.0 nie. NSString nie jest częścią języka Swift, jest częścią struktury Foundation.
Dániel Nagy
75

To działa, NSStringwięc możesz go używać w następujący sposób:

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

Teraz możesz użyć tego rozszerzenia, które najpierw skonwertuje twoje Stringna, NSStringa następnie wykona operację.

Twój kod będzie wyglądał następująco:

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

Oto kilka innych metod użycia:

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

Odniesienie z TUTAJ .

Dla 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
źródło
12
Chociaż jest to prawidłowe rozwiązanie, istnieje powód, dla którego firma Apple usunęła te metody - używanie ścieżek do lokalizowania zasobów jest przestarzałe, a NSURLzamiast tego należy używać s. Tylko mówię.
Charlie Monroe
snippet: String (NSString (string: path) .stringByAppendingPathComponent (imageName)) ... poza tym, całkiem zgadzam się z @CharlieMonroe
Bobjt
1
@CharlieMonroe, jeśli tak jest naprawdę, dlaczego w SDK nadal istnieje kilka metod, które nie akceptują adresu URL jako ścieżki?
Joris Mans,
@JorisMans Są to zwykle starsze metody (dostępne od 10.0 lub wcześniej). Odkąd pojawił się sandboxing, nie ma możliwości przekazania ścieżki z np. Zakładką appscope - zamiast tego potrzebny jest adres URL. Apple wolno aktualizuje interfejsy API, z których korzysta tylko kilka osób. A może masz przykład ostatnio dodanego API (ostatnie 3-4 lata)?
Charlie Monroe
1
@IulianOnofrei - Bo trzeba być przy użyciu checkResourceIsReachable()albo checkPromisedItemIsReachable()na URLzamiast. FileManagerjest nadal klasą ObjC NSFileManagerz NSusuniętym przedrostkiem dla Swift i fileExistsAtPathistniała od czasu OS X 10.0. Świat ewoluował od tego czasu, a ponieważ aplikacje są piaskownicą (co jest mniej oczywiste w iOS), plik może istnieć, po prostu możesz nie mieć uprawnień do jego przeglądania; plik może również znajdować się w chmurze itp. Dlatego prostą BOOLmetodę zastępuje się czymś bardziej złożonym URL, ale poprawnym semantycznie.
Charlie Monroe
30

Po prostu zawiń swój sznurek jako NSString.

let writePath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("instagram.igo")
Jeffrey Neo
źródło
fajny… Stringklasa nie ma tego, ale NSStringistnieje! ma sens.
preetam,
16

dla Swift 3 :

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

lub lepiej utwórz to rozszerzenie:

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

stosowanie:

 let writePath = NSTemporaryDirectory().appendingPathComponent(directoryname)
Wiaczesław
źródło
6

Rozwiązanie Swift 3:

Oto funkcja pozwalająca uzyskać ścieżkę do katalogu dokumentów-

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

Jak używać:

    getDocumentsDirectory.appendingPathComponent("google.com")

Wynik:

    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
źródło
5

Dla 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
źródło
2

Zamiast tego można użyć metody URLByAppendingPathComponent (). Pamiętaj, że powinieneś przyciąć ciąg ścieżki, aby usunąć prefiks „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
źródło
0

Wykonaj następujące czynności:

(("\(fileName)" as NSString).lastPathComponent as NSString).stringByDeletingPathExtension
Mauro Delazeri
źródło
0

Spróbowałem tego i to rozwiązało problem.

przed:

let localPath = documentDirectory.URLByAppendingPathComponent(imageName)

po:

let localPath = (documentDirectory as NSString).appendingPathComponent(imageName)
Miah G.
źródło
-1

Jeśli użycie NSStringmetod ścieżkowych (zamiast Stringmetod URL) jest dopuszczalne, znacznie łatwiej jest rozszerzyć Stringo właściwość obliczoną lub metodę zwracającą jej wartość jako NSString(zamiast powielać żądane metody w Stringrozszerzeniu):

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

i wtedy:

swiftStringPath.ns.appendingPathComponent("whateva")
swiftStringPath.ns.deletingPathExtension
Rosyjski
źródło
-2

Szybki 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
źródło