stringByAppendingPathComponent n'est pas disponible

132

Mon application partage la photo sur Instagram, pour ce faire, elle l'enregistre d'abord dans un répertoire temporaire:

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

Il fonctionnait Swift 1.2, mais ne fonctionne pas Swift 2.0.

Le message d'erreur donné est:

stringByAppendingPathComponent n'est pas disponible: utilisez plutôt URLByAppendingPathComponent sur NSURL.

Maysam
la source

Réponses:

145

Il semble que la méthode stringByAppendingPathComponentsoit supprimée dans Swift 2.0, donc ce que le message d'erreur suggère est d'utiliser:

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

Mettre à jour:

URLByAppendingPathComponent()a été remplacé par appendingPathComponent()alors faites à la place:

let writePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("instagram.igo")
Dániel Nagy
la source
si vous allez utiliser cette conception, vous aurez des problèmes comme convertir l'espace en% 20Application%20Support
Roman
non, Swift 2.0 peut utiliser stringByAppendingPathComponent, voir ma réponse ci-dessous.
Jeffrey Neo
2
@JeffreyNeo oui, mais ce n'est pas une NSURLméthode mais unNSString
Dániel Nagy
@ DánielNagy Je veux dire que vous avez dit que " stringByAppendingPathComponentest supprimé dans Swift 2.0" n'est pas correct, et @Maysam n'a pas demandé uniquement la NSURLméthode.
Jeffrey Neo
4
@JeffreyNeo en fait, c'est correct, car dans Swift 1.2, String avait une méthode appelée stringByAppendingPathComponent, mais pas String de Swift 2.0. Et NSString ne fait pas partie du langage Swift, il fait partie du framework Foundation.
Dániel Nagy
75

Cela fonctionne pour NSStringque vous puissiez l'utiliser comme ceci:

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

Vous pouvez maintenant utiliser cette extension qui convertira votre Stringen NSStringpremier, puis effectuera l'opération.

Et votre code sera:

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

Voici quelques autres méthodes d'utilisation:

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

Référence de ICI .

Pour 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
la source
12
Bien que ce soit une solution valide, il y a une raison pour laquelle Apple a supprimé ces méthodes - l'utilisation de chemins pour localiser les ressources est obsolète et NSURLs doit être utilisé à la place. Juste dire.
Charlie Monroe
snippet: String (NSString (string: path) .stringByAppendingPathComponent (imageName)) ... sinon, tout à fait d'accord avec @CharlieMonroe
Bobjt
1
@CharlieMonroe si c'est vraiment le cas, pourquoi y a-t-il encore un tas de méthodes qui n'acceptent pas une URL comme chemin, dans le SDK?
Joris Mans
@JorisMans Ce sont généralement des méthodes plus anciennes (disponibles depuis la version 10.0, ou tôt après). Depuis l'introduction du sandbox, il n'y a aucun moyen de passer un chemin avec par exemple un signet appscope - vous avez besoin d'une URL à la place. Apple met du temps à mettre à jour les API que seules quelques personnes utilisent. Ou avez-vous un exemple d'API récemment ajoutée (les 3-4 dernières années)?
Charlie Monroe
1
@IulianOnofrei - Parce que vous devriez utiliser checkResourceIsReachable()ou checkPromisedItemIsReachable()à la URLplace. FileManagerest toujours une classe ObjC NSFileManageravec le NSpréfixe supprimé pour Swift et fileExistsAtPathétait là depuis OS X 10.0. Le monde a évolué depuis et comme les applications sont en bac à sable (ce qui est moins évident sur iOS), le fichier peut exister, vous n'avez peut-être pas la permission de le voir; aussi, le fichier peut être dans le cloud, etc. C'est pourquoi la BOOLméthode simple est remplacée par quelque chose de plus complexe pour URL, mais plus sémantiquement correct.
Charlie Monroe
30

Enroulez simplement votre chaîne comme NSString.

let writePath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("instagram.igo")
Jeffrey Neo
la source
cool un .. la Stringclasse n'a pas cela mais NSStringexiste! logique.
préétam
16

pour Swift 3 :

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

ou mieux créer cette extension:

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

usage:

 let writePath = NSTemporaryDirectory().appendingPathComponent(directoryname)
Vyacheslav
la source
6

Solution Swift 3:

Voici une fonction pour obtenir le chemin du répertoire des documents-

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

Comment utiliser:

    getDocumentsDirectory.appendingPathComponent("google.com")

Résultat:

    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
la source
5

Pour 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
la source
2

Vous pouvez utiliser URLByAppendingPathComponent () à la place. Veuillez noter que vous devez couper la chaîne de chemin pour supprimer le préfixe "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
la source
0

Procédez comme suit:

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

J'ai essayé ceci et cela a résolu le problème.

avant:

let localPath = documentDirectory.URLByAppendingPathComponent(imageName)

après:

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

Si l'utilisation de NSStringméthodes de chemin (au lieu de Stringméthodes URL) est acceptable, il est beaucoup plus facile d'étendre Stringavec une propriété calculée ou une méthode renvoyant sa valeur comme NSString(au lieu de dupliquer les méthodes souhaitées dans l' Stringextension):

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

puis:

swiftStringPath.ns.appendingPathComponent("whateva")
swiftStringPath.ns.deletingPathExtension
russe
la source
-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
la source