Swift で Objective-C の @synchronized
環境: Swift version 1.1 (swift-600.0.56.1)
クリティカルセクションを作りたいとき、Objective-C の場合は
@synchronized(obj) { ... }
となるところを Swift の場合は
objc_sync_enter(obj)
...
objc_sync_exit(obj)
とする。
exit 漏れが怖いのでラップする。
func sync(lock: AnyObject, proc: () -> ()) { objc_sync_enter(lock) proc() objc_sync_exit(lock) }
sync(obj) { ... }
shenzhen を使ってコマンドラインで iOS アプリをビルド
環境: shenzhen (0.10.2)
インストール
$ gem install shenzhen
ビルド
$ ipa build -w XXXXX.xcworkspace -s スキーマ --embed XXXXX.mobileprovision
確認
$ ipa info XXXXX.ipa
iOS で半透明なモーダルビューを表示する
環境: Swift version 1.1 (swift-600.0.56.1)
自作 UIViewController をモーダルで表示する
//SomeViewController view.backgroundColor = UIColor(white: 0.2, alpha: 0.2)
//呼び出し側 let controller = SomeViewController() controller.modalPresentationStyle = .OverCurrentContext controller.modalTransitionStyle = .CrossDissolve presentViewController:actionSheetViewController(true, completion:nil)
UIActionSheet を使う
単にボタンを表示したいだけの場合、 iOS7 までは UIActionSheet、iOS8 では UIAlertController を使う。
iOS のバージョン毎に分岐するのは面倒なので CocoaPods で RMUniversalAlert を追加すると便利。
# Podfile pod 'RMUniversalAlert'
RMUniversalAlert.showActionSheetInViewController(self, withTitle: "タイトル", message: "メッセージ", cancelButtonTitle: "キャンセル", destructiveButtonTitle: "削除", otherButtonTitles: ["編集", "履歴"], tapBlock: { index in switch index { case UIAlertControllerBlocksCancelButtonIndex: // "キャンセル" をタップした場合の動作 case UIAlertControllerBlocksDestructiveButtonIndex: // "削除" をタップした場合の動作 case UIAlertControllerBlocksFirstOtherButtonIndex: // "編集" をタップした場合の動作 case UIAlertControllerBlocksFirstOtherButtonIndex + 1: // "履歴" をタップした場合の動作 default: break } return })
追記
最新版の RMUniversalAlert(0.6) の場合、インタフェースが上記のような記述から以下のように変更されている。
- tapBlock に渡す関数の型が Int -> () から (RMUniversalAlert,Int) -> () に変更
- これに伴って、UIAlertControllerBlocksCancelButtonIndex, UIAlertControllerBlocksCancelButtonIndex, UIAlertControllerBlocksDestructiveButtonIndex, UIAlertControllerBlocksFirstOtherButtonIndex のような定数が無くなり、これらの値は RMUniversalAlert#{cancelButtonIndex, destructiveButtonIndex, firstOtherButtonIndex} から取得するようになった
- iPad 用に引数 popoverPresentationControllerBlock の追加
以下のように記述する。
RMUniversalAlert.showActionSheetInViewController(self, withTitle: "タイトル", message: "メッセージ", cancelButtonTitle: "キャンセル", destructiveButtonTitle: "削除", otherButtonTitles: ["編集", "履歴"], popoverPresentationControllerBlock:{ $0.sourceView = popoverView /* どの UIView の上に ActionSheet を表示するか */ $0.sourceRect = view.frame }, tapBlock: { (alertView, index) in switch index { case alertView.cancelButtonIndex: // "キャンセル" をタップした場合の動作 case alertView.destructiveButtonIndex: // "削除" をタップした場合の動作 case alertView.firstOtherButtonIndex: // "編集" をタップした場合の動作 case alertView.firstOtherButtonIndex + 1: // "履歴" をタップした場合の動作 default: break } return })
Xcode6 で SourceKitService Crashed が頻発する場合の対処
SourceKitService Crashed が頻発するとコーディングが阻害されるし、悪い場合は、シンタックスハイライトやコード補完が効かなくなる。
根本的な解決方法は分からない。
とりあえず DerivedData ディレクトリを削除して Xcode を再起動すると改善する。
Xcode 6.1.1 (6A2008a) で確認。
DerivedData ディレクトリは Preference の Location タブを開き、DerivedData ディレクトリの右矢印をクリックすると Finder で開ける。
削除した状態でビルドした時にエラーが出る場合は、一旦 Product > Clean する必要がある。
Xcode での開発で trailing whitespace を無くす
Xcode 6.1.1 で確認。
Preferences.. > Text Editing タブ > Editing タブ > While Editing: の
- Automatically trim trailing whiltespace
- Incliuding whitespace-only lines
にチェックを入れる 。