Stringのpath操作系のメソッドをExtensionで復活させる


(2016/09/19: 投稿をSwift3.0に対応)

stringByAppendingPathComponent: といったpath操作系のメソッドがSwift2.0以降 Stringから直接呼び出すことができない(メソッドがなくなった)ので、これを Extension で生やしてみます。
(厳密には、 URLでこれらのメソッドが使えますが、毎回 String→URL→String とするのはおそろしくだるいので、こちらのほうがお手軽です。

Swift 3.0

import Foundation

extension String {

    private var ns: NSString {
        return (self as NSString)
    }

    public func substring(from index: Int) -> String {
        return ns.substring(from: index)
    }

    public func substring(to index: Int) -> String {
        return ns.substring(to: index)
    }

    public func substring(with range: NSRange) -> String {
        return ns.substring(with: range)
    }

    public var lastPathComponent: String {
        return ns.lastPathComponent
    }

    public var pathExtension: String {
        return ns.pathExtension
    }

    public var deletingLastPathComponent: String {
        return ns.deletingLastPathComponent
    }

    public var deletingPathExtension: String {
        return ns.deletingPathExtension
    }

    public var pathComponents: [String] {
        return ns.pathComponents
    }

    public func appendingPathComponent(_ str: String) -> String {
        return ns.appendingPathComponent(str)
    }

    public func appendingPathExtension(_ str: String) -> String? {
        return ns.appendingPathExtension(str)
    }
}

ポイントは、一度StringNSStringにしてから、NSStringのメソッドとしてそれぞれ呼び出してあげます。


// ---
    let dir = "path/to/foo"
    let path = dir.appendingPathComponent("test.txt") // OK!
    print(path) // "path/to/foo/test.txt"

〜Swift2.3

StringExtensions.swift
//  StringExtensions.swift

import Foundation

extension String {

    /// String -> NSString に変換する
    func to_ns() -> NSString {
        return (self as NSString)
    }

    func substringFromIndex(index: Int) -> String {
        return to_ns().substringFromIndex(index)
    }

    func substringToIndex(index: Int) -> String {
        return to_ns().substringToIndex(index)
    }

    func substringWithRange(range: NSRange) -> String {
        return to_ns().substringWithRange(range)
    }

    var lastPathComponent: String {
        return to_ns().lastPathComponent
    }

    var pathExtension: String {
        return to_ns().pathExtension
    }

    var stringByDeletingLastPathComponent: String {
        return to_ns().stringByDeletingLastPathComponent
    }

    var stringByDeletingPathExtension: String {
        return to_ns().stringByDeletingPathExtension
    }

    var pathComponents: [String] {
        return to_ns().pathComponents
    }

    var length: Int {
        return self.characters.count
    }

    func stringByAppendingPathComponent(path: String) -> String {
        return to_ns().stringByAppendingPathComponent(path)
    }

    func stringByAppendingPathExtension(ext: String) -> String? {
        return to_ns().stringByAppendingPathExtension(ext)
    }

}

// ---
    let dir = "path/to/foo"
    let path = dir.stringByAppendingPathComponent("test.txt") // OK!
    print(path) // "path/to/foo/test.txt"