Swift

...now browsing by category

 

XcodeでSwiftのリファクタリングができないから、renameの代わりにターミナルのコマンドで一括置換してみた

木曜日, 9月 17th, 2015

Xcode7の正式版が出たというのに、未だにSwiftのリファクタリング機能が実装されていません。特にrenameはよく使うので困りものです。さすがにちまちま置換していくのはとても面倒なので、ターミナルのコマンドで一括置換しました。

find -E . -regex ".*\.(swift|storyboard)" | xargs perl -i -pe 's/\bOldName\b/NewName/g'

これでカレントディレクトリ配下の *.swift ファイルおよび *.storyboard ファイル内の、「OldName」を「NewName」に置換できます。

「.*\.(swift|storyboard)」の部分で対象とするファイルを指定しています。「-E」「-regex」 は拡張正規表現を使うためのオプションで、両方必要なようです。

「OldName」の前後の「\b」は単語の区切りを示します。これがあると「HogeOldName」や「OldNameMoge」などは対象外になります。

最初、perlの代わりにsedを使おうと思っていたのですが、正規表現で「\b」が使えなかったり、バックアップファイルが残ってしまったりするので、perlに変えました。

NSRange を Range<String.Index> に変換

火曜日, 4月 7th, 2015

Swift でちょっと苦労したのでメモ。

UITextFieldDelegate で返される NSRange を String の操作に使おうとしたら、そのままでは使えませんでした。調べてみると String の操作メソッドでは Range<String.Index> が使わていました。文字の位置を表す型として int や NSInteger ではなく、String.Index という専用の型が設けられたようです。

int から String.Index には直接変換できないので、advance関数を利用します。苦労の末に以下の方法で NSRange から Range<String.Index> への変換が出来ました。

    func rangeWith(range: NSRange) -> Range<String.Index> {
        var string = "dummy"
        var startIndex = advance(string.startIndex, range.location)
        var endIndex = advance(startIndex, range.length)
        return Range(start: startIndex, end: endIndex)
    }

ダミーのString使ったりするのはイマイチなので、なんか良い方法はないかなー