ios - from - swift set string



Come dividere il nome del file dall'estensione del file in Swift? (13)

Soluzione Swift 4

Questa soluzione funzionerà per tutte le istanze e non dipende dall'analisi manuale della stringa.

let path = "/Some/Random/Path/To/This.Strange.File.txt"

let fileName = URL(fileURLWithPath: path).deletingPathExtension().lastPathComponent

Swift.print(fileName)

L'output risultante sarà

This.Strange.File

https://src-bin.com

Dato il nome di un file nel bundle, voglio caricare il file nella mia app Swift. Quindi ho bisogno di usare questo metodo:

let soundURL = NSBundle.mainBundle().URLForResource(fname, withExtension: ext)

Per qualsiasi motivo, il metodo richiede il nome file separato dall'estensione del file. Bene, è abbastanza facile separare i due nella maggior parte delle lingue. Ma finora non lo trovo così in Swift.

Quindi ecco quello che ho:

var rt: String.Index = fileName.rangeOfString(".", options:NSStringCompareOptions.BackwardsSearch)
var fname: String = fileName .substringToIndex(rt)
var ext = fileName.substringFromIndex(rt)

Se non includo la digitazione sulla prima riga, ottengo errori sulle due righe successive. Con esso, ricevo un errore sulla prima riga:

Cannot convert the expression's type '(UnicodeScalarLiteralConvertible, options: NSStringCompareOptions)' to type 'UnicodeScalarLiteralConvertible'

Come posso dividere il nome file dall'estensione? C'è un modo elegante per farlo?

Ero entusiasta di Swift perché sembrava un linguaggio molto più elegante dell'obiettivo C. Ma ora sto scoprendo che ha una sua ingombro.

Secondo tentativo: ho deciso di creare il mio metodo di ricerca di stringhe:

func rfind(haystack: String, needle: Character) -> Int {
    var a = Array(haystack)

    for var i = a.count - 1; i >= 0; i-- {
        println(a[i])
        if a[i] == needle {
            println(i)
            return i;
        }
    }
    return -1
}

Ma ora ricevo un errore sulla riga var rt: String.Index = rfind(fileName, needle: ".") :

'Int' is not convertible to 'String.Index'

Senza il cast, ricevo un errore sulle due righe successive.

Qualcuno può aiutarmi a dividere questo nome file ed estensione?


Answer #1

Come sottolineato nel commento, puoi usarlo.

let filename: NSString = "bottom_bar.png"
let pathExtention = filename.pathExtension
let pathPrefix = filename.stringByDeletingPathExtension

Answer #2

Forse sto arrivando troppo tardi per questo, ma una soluzione che ha funzionato per me e considera abbastanza semplice sta usando la direttiva del compilatore #file . Ecco un esempio in cui ho una classe FixtureManager , definita in FixtureManager.swift nella FixtureManager.swift / Tests / MyProjectTests / Fixtures directory. This works both in Xcode and with directory. This works both in Xcode and with test rapidi`

import Foundation

final class FixtureManager {

    static let fixturesDirectory = URL(fileURLWithPath: #file).deletingLastPathComponent()

    func loadFixture(in fixturePath: String) throws -> Data {
        return try Data(contentsOf: fixtureUrl(for: fixturePath))
    }

    func fixtureUrl(for fixturePath: String) -> URL {
        return FixtureManager.fixturesDirectory.appendingPathComponent(fixturePath)
    }

    func save<T: Encodable>(object: T, in fixturePath: String) throws {
        let data = try JSONEncoder().encode(object)
        try data.write(to: fixtureUrl(for: fixturePath))
    }

    func loadFixture<T: Decodable>(in fixturePath: String, as decodableType: T.Type) throws -> T {
        let data = try loadFixture(in: fixturePath)
        return try JSONDecoder().decode(decodableType, from: data)
    }

}

Answer #3

Funziona con Swift 3 / Swift 4. Aggiunta di questi comportamenti alla classe String :

extension String {

    func fileName() -> String {
        return NSURL(fileURLWithPath: self).deletingPathExtension?.lastPathComponent ?? ""
    }

    func fileExtension() -> String {
        return NSURL(fileURLWithPath: self).pathExtension ?? ""
    }
}

Esempio:

let file = "image.png"
let fileNameWithoutExtension = file.fileName()
let fileExtension = file.fileExtension()

Answer #4

In Swift 2.1, sembra che l'attuale modo per farlo sia:

let filename = fileURL.URLByDeletingPathExtension?.lastPathComponent
let extension = fileURL.pathExtension

Answer #5

In Swift puoi passare a NSString per ottenere l'estensione più velocemente:

extension String {
    func getPathExtension() -> String {
        return (self as NSString).pathExtension
    }
}

Answer #6

Prova questo per una semplice soluzione Swift 4

extension String {
    func stripExtension(_ extensionSeperator: Character = ".") -> String {
        let selfReversed = self.reversed()
        guard let extensionPosition = selfReversed.index(of: extensionSeperator) else {  return self  }
        return String(self[..<self.index(before: (extensionPosition.base.samePosition(in: self)!))])
    }
}

print("hello.there.world".stripExtension())
// prints "hello.there"

Answer #7

Questo è con Swift 2, Xcode 7: se hai già il nome del file con l'estensione, puoi passare l'intero nome del file come primo parametro e una stringa vuota come secondo parametro:

let soundURL = NSBundle.mainBundle()
    .URLForResource("soundfile.ext", withExtension: "")

In alternativa zero, poiché funziona anche il parametro extension.

Se disponi di un URL e desideri ottenere il nome del file stesso per qualche motivo, puoi farlo:

soundURL.URLByDeletingPathExtension?.lastPathComponent

Swift 4

let soundURL = NSBundle.mainBundle().URLForResource("soundfile.ext", withExtension: "")
soundURL.deletingPathExtension().lastPathComponent

Answer #8

Swift 3.0

 let sourcePath = NSURL(string: fnName)?.pathExtension
 let pathPrefix = fnName.replacingOccurrences(of: "." + sourcePath!, with: "")

Answer #9

Swift 4.2 più recente funziona in questo modo:

extension String {
    func fileName() -> String {
        return URL(fileURLWithPath: self).deletingPathExtension().lastPathComponent
    }

    func fileExtension() -> String {
        return URL(fileURLWithPath: self).pathExtension
    }
}

Answer #10

Un modo migliore (o almeno un'alternativa in Swift 2.0) è usare la proprietà String pathComponents. Ciò divide il percorso in una matrice di stringhe. per esempio

if let pathComponents = filePath.pathComponents {
    if let last = pathComponents.last {
        print(" The last component is \(last)") // This would be the extension
        // Getting the last but one component is a bit harder
        // Note the edge case of a string with no delimiters!
    }
}
// Otherwise you're out of luck, this wasn't a path name!

Answer #11

Una risposta pulita per Swift 4 con un'estensione off di PHAsset :

import Photos

extension PHAsset {
    var originalFilename: String? {
        if #available(iOS 9.0, *),
            let resource = PHAssetResource.assetResources(for: self).first {
            return resource.originalFilename
        }

        return value(forKey: "filename") as? String
    }
}

Come notato in XCode, originalFilename è il nome dell'asset nel momento in cui è stato creato o importato.


Answer #12

Soluzione estesa Swift 3.x:

extension String {
    func lastPathComponent(withExtension: Bool = true) -> String {
        let lpc = self.nsString.lastPathComponent
        return withExtension ? lpc : lpc.nsString.deletingPathExtension
    }

    var nsString: NSString {
         return NSString(string: self)
    }
}

let path = "/very/long/path/to/filename_v123.456.plist"
let filename = path.lastPathComponent(withExtension: false)

la costante del nome file ora contiene " nome_v123.456 "





swift