Это с Swift 2, Xcode 7: если у вас есть имя файла с уже добавленным расширением, вы можете передать полное имя файла в качестве первого параметра и пустую строку в качестве второго параметра:
let soundURL = NSBundle.mainBundle()
.URLForResource("soundfile.ext", withExtension: "")
Альтернативно, поскольку параметр расширения также работает.
Если у вас есть URL-адрес, и вы хотите получить имя самого файла по какой-либо причине, вы можете сделать это:
soundURL.URLByDeletingPathExtension?.lastPathComponent
Swift 4
let soundURL = NSBundle.mainBundle().URLForResource("soundfile.ext", withExtension: "")
soundURL.deletingPathExtension().lastPathComponent
В Swift 2.1 кажется, что текущий способ сделать это:
let filename = fileURL.URLByDeletingPathExtension?.lastPathComponent
let extension = fileURL.pathExtension
Очищенный ответ для Swift 4 с расширением от 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
}
}
Как отмечено в XCode, исходное имя файла - это имя актива в момент его создания или импорта .
Лучший способ (или, по крайней мере, альтернатива в Swift 2.0) - использовать свойство String pathComponents. Это разделяет путь в массив строк. например
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!
В Swift вы можете перейти на NSString
, чтобы быстрее получить расширение:
extension String {
func getPathExtension() -> String {
return (self as NSString).pathExtension
}
}
Попробуйте это для простого решения 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"
Как указано в комментарии, вы можете использовать это.
let filename: NSString = "bottom_bar.png"
let pathExtention = filename.pathExtension
let pathPrefix = filename.stringByDeletingPathExtension
Возможно, я слишком поздно для этого, но решение, которое сработало для меня и считалось довольно простым, - это использовать #file
компилятор. Вот пример, когда у меня есть класс FixtureManager
, определенный в FixtureManager.swift
внутри теста / Tests / MyProjectTests / Fixtures directory. This works both in Xcode and with
swift test`
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)
}
}
Это решение будет работать для всех экземпляров и не зависит от ручного анализа строки.
let path = "/Some/Random/Path/To/This.Strange.File.txt"
let fileName = URL(fileURLWithPath: path).deletingPathExtension().lastPathComponent
Swift.print(fileName)
Результирующим выходом будет
This.Strange.File
Строки в Свифте могут быть определенно сложными. Если вам нужен чистый метод Swift, вот как бы я это сделал:
find
, чтобы найти последнее вхождение "."
в reverse
строки advance
, чтобы получить правильный индекс "."
в исходной строке String
subscript
, которая принимает IntervalType
, чтобы получить строки Что-то вроде этого:
func splitFilename(str: String) -> (name: String, ext: String)? {
if let rDotIdx = find(reverse(str), ".") {
let dotIdx = advance(str.endIndex, -rDotIdx)
let fname = str[str.startIndex..<advance(dotIdx, -1)]
let ext = str[dotIdx..<str.endIndex]
return (fname, ext)
}
return nil
}
Который будет использоваться как:
let str = "/Users/me/Documents/Something.something/text.txt"
if let split = splitFilename(str) {
println(split.name)
println(split.ext)
}
Какие выходы:
/Users/me/Documents/Something.something/text
txt
Или, просто используйте имеющиеся методы NSString
, такие как pathExtension
и stringByDeletingPathExtension
.
Они по какой-то причине избавились от pathExtension.
let str = "Hello/this/is/a/filepath/file.ext"
let l = str.componentsSeparatedByString("/")
let file = l.last?.componentsSeparatedByString(".")[0]
let ext = l.last?.componentsSeparatedByString(".")[1]
Создает уникальный URL-адрес формы, включая две предыдущие папки
func createFileNameFromURL (colorUrl: URL) -> String {
var arrayFolders = colorUrl.pathComponents
// -3 because last element from url is "file name" and 2 previous are folders on server
let indx = arrayFolders.count - 3
var fileName = ""
switch indx{
case 0...:
fileName = arrayFolders[indx] + arrayFolders[indx+1] + arrayFolders[indx+2]
case -1:
fileName = arrayFolders[indx+1] + arrayFolders[indx+2]
case -2:
fileName = arrayFolders[indx+2]
default:
break
}
return fileName
}
В Swift 2.1 String.pathExtension больше не доступно. Вместо этого вам нужно определить его с помощью преобразования NSURL:
NSURL(fileURLWithPath: filePath).pathExtension
Работает с Swift 3 / Swift 4. Добавляем эти поведения в класс String
:
extension String {
func fileName() -> String {
return NSURL(fileURLWithPath: self).deletingPathExtension?.lastPathComponent ?? ""
}
func fileExtension() -> String {
return NSURL(fileURLWithPath: self).pathExtension ?? ""
}
}
Пример:
let file = "image.png"
let fileNameWithoutExtension = file.fileName()
let fileExtension = file.fileExtension()
SWIFT 3.x Самое короткое родное решение
let fileName:NSString = "the_file_name.mp3"
let onlyName = fileName.deletingPathExtension
let onlyExt = fileName.pathExtension
Нет расширения или каких-либо дополнительных материалов (я тестировал на основе решения @gabbler для Swift 2)
Swift 3.0
let sourcePath = NSURL(string: fnName)?.pathExtension
let pathPrefix = fnName.replacingOccurrences(of: "." + sourcePath!, with: "")
Расширенное решение 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)
константа имени файла теперь содержит « filename_v123.456 "