The Pragmatic Ball boy

iOSを中心にやってる万年球拾いの老害エンジニアメモ

Swift

UIViewControllerがMainActorだから安心できるわけではない

前回の記事でUIViewControllerとMainActorのことについてかきました。UIViewControllerはMainActorなのでMainスレッドで実行されることは保証されていて安心!かと思いきやそうでもなかったのです。 以下のMainActorであるViewModelをMainActorではないクラ…

UIViewControllerからMainActorを呼ぶときにawaitしなくてよい理由

SwiftConcurrencyでは普通actorのメソッドを呼んだりするときはawaitしなければならないですが、UIViewControllerからMainActorのメソッドを呼ぶときはawaitせずに普通に呼べてしまいます。 これはなぜかというとUIViewControllerもMainActorだからです。 UI…

Swift Concurrencyのパフォーマンス

Swift Concurrencyは並列プログラミングの書きやすさや便利さがよくなっただけでなくパフォーマンスも改善されています。 これまでの問題 これまでのGCDを使った並列処理では、CPU Coreに対して一つスレッドを割り当てそれをスレッドプールにプールして再利…

Swift ConcurrencyのActor reentrancy

SwiftでActorsが導入され、actorを使えば簡単にスレッドセーフにすることができるようになりました。 ただこれでrace conditionやdead lockといった並行プログラミングにおける問題が解決されるわけではありません。 Actor reentrancy SwiftのActors(正確に…

peripheryの特定ブランチをビルドしてつかう

Swiftの使ってないコードを消すperipheryとツールがありますが、 Xcode11の対応版がまだマージされていなくて使えません。 xcode11というブランチがあってそれを使うと一応使うことができます。ただビルドしないといけないのでそのビルド方法です。 peripher…

SwiftUIのViewで条件によってViewを出し分ける方法

potatotips #64でLTした内容です。 SwiftUIのViewで条件によってViewをだしわけたいことがたまにあるかと思います。 SwiftUIでこのように条件によってViewを出し分けるようなコードを書いてみます。 var body: some View { if imageName.isEmpty { return Te…

Nimbleでtupleの比較

Nimbleでtupleをequal()で比較してもコンパイルに通りません。 let tuple = (1, 2) expect(tuple).to(equal((1, 2))) 原因 これはtupleがEquatableではないからです 対策 これはどうしようもないので以下のようにequalを使わずに回避するしかなさそうです ex…

@propertyDelegateと@propertyWrapperの違い

2019/06/25 現在の情報 Swift EvolutionのProperty Wrappersを見ると@propertyWrapper ですが、 AppleのドキュメントのStateを見ると @propertyDelegateになっています。 state 原因 仕様策定段階で名前が変わった 詳細 ここに書いてあるように最初はpropert…

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0)はなぜnanosecondではなくsecondになるか

あんまり気にしてる人はいないかもしれないですが、普段何も考えずに DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) を使っているとdeadline: DispatchTime はsecond単位っぽく感じるかもしれないですが、nanosecondです。 DispatchTime DispatchT…

SwiftのDictionaryのsubscriptとupdateValueの違い

SwiftでDictionaryの値を追加、変更するのに2通りのやりかたがあります。 ひとつはsubscript、dict["key"] = "value" もうひとつはupdateValue、dict.updateValue("value", forKey: "key") です。 どちらを使ってもDictionaryの値を変更できますが、微妙に…

RxSwiftのVariableとBehaviorRelayとBehaviorSubjectの違い

動機 RxSwiftのVariableがdeprecatedになったということで、その代わりとしてBehaviorRelayに置き換えようと思ったときに、BehaviorRelayに単純に置き換えてよいのか?BehaviorSubjectもあるけどこっちはどうなんだっけ?という視点で調べてみました。 結論 …

linuxでSwiftのObjCBool.boolValueを呼ぶとerror

不具合 SwiftでObjCBoolのboolValueをこのように呼び出すと var isDir: ObjCBool = false let isExist = fm.fileExists(atPath: directory, isDirectory: &isDir) XCTAssertTrue(isDir.boolValue) osxだと大丈夫だけどlinux環境だとerrorになる・・ error: v…

SwiftTweets 2018 Winterの資料のまとめ

SwiftTweets 2018 Winterの資料のまとめです。 https://swift-tweets.github.io/2018-winter 発表 どうやってSwiftのOSSをメンテナンスしていくか https://twitter.com/ikesyo/status/954687472369201155 Swift Foundationにコントリビュートする https://tw…

AutolayoutでレイアウトしたViewを外して元に戻す

InterfaceBuilderやStoryboardでAutolayoutを使って配置したViewをremoveFromSuperviewしてから、 再度addSubviewしたい!ということがたまにあります。 普通にremoveFromSuperviewしてaddSubviewすると元には戻りません。 なぜならremoveFromSuperviewした…

独自のNotification名を追加

独自のNotification名を追加する場合はこんな書き方がよいような気がします。 extension Notification.Name { struct AppName { public static let DidLogin = Notification.Name(rawValue: "com.example.appname.didLogin") } } 通知名の文字列には通知名の…

SwiftでKVOするときはObjective-Cのプロパティ名を使う

当たり前といえば当たり前なんですが、 iOSのKVO(addObserver(_:forKeyPath:options:context:))はObjective-CのNSObjectのメソッドなので、指定するkeyPathはObjective-Cのプロパティ名じゃないとだめです。 例えばUIViewのisHiddenをKVOしたい場合は↓のよう…

TwitterKitを使ってログインするときの注意点

TwitterKitを使ってログインするときの注意点を2点 1. Twitterアカウントを登録しているかで挙動が変わる TwitterKitを使ってTwitterログインするときに、TwitterのアカウントをiOSに設定しているかどうかで挙動が変わります。 (2017年1月時点) iOSの設定…

Swiftでの複数にデリゲート multicast delegate

Swiftにはweak reference arrayがないので、NSHashTableを利用します protocol SampleDelegate : class { func sampleDelegateDidFinish() } class SampleClass { let delegates = NSHashTable<AnyObject>() // AnyObjectをSampleDelegateにするとSwift3時点ではコンパ</anyobject>…

Swift3.0.1で若干変わったIntなどの数値型⇔AnyObjectのcast

Xcode8(Swift3.0.0)だと↓のテストは通るんですが、 import XCTest @testable import TypeTest class TypeTests: XCTestCase { func testType_WhenIntToAnyObject() { let intValue = ["hoge": Int(1) as AnyObject] XCTAssertTrue(intValue["hoge"] is Int) …

CGRectの新旧書き方対応表

古 新 CGRectGetWidth( rect ) rect.width CGRectGetHeight( rect ) rect.height CGRectGetMinX( rect ) rect.minX CGRectGetMidX( rect ) rect.midX CGRectGetMaxX( rect ) rect.maxX CGRectGetMinY( rect ) rect.minY CGRectGetMidY( rect ) rect.midY CGR…

動画のフォトアルバムへの保存

動画のフォトアルバムへの保存 iOS8まで import AssetsLibrary ... ALAssetsLibrary().writeVideoAtPathToSavedPhotosAlbum(filePathURL) { _ in // 完了後の処理 } iOS9以降 import Photos ... PHPhotoLibrary.sharedPhotoLibrary().performChanges( { PHAs…

UITableViewCellのセパレーターを消す

セルのセパレーター消すやつ override func awakeFromNib() { separatorInset = UIEdgeInsets(top: 0, left: bounds.width, bottom: 0, right: 0) }

RxSwiftでTableView その3

RxTableViewSectionedReloadDataSourceでは複数Sectionに対応できましたが、 Section単位でreloadData()がされてしまっていました。 今回はRxTableViewSectionedAnimatedDataSourceを使ってみます RxTableViewSectionedAnimatedDataSource ViewControllerはR…

RxSwiftでTableView その2

rx_itemsWithCellIdentifierではSection1つしかダメでした。 複数Sectionを使う方法としていくつかあるっぽいのですが、 まずRXTableViewSectionedReloadDataSourceを使ってみます。 RXTableViewSectionedReloadDataSource これはRxSwiftには含まれておらず…

RxSwiftでTableView その1

RxSwiftでTableViewとdatasourceをbindingさせる方法はいくつかあるようなので1つずつ見ていきます。 今回はrx_itemsWithCellIdentifilerを使ってみます。 rx_itemsWithCellIdentifier 単にSectionが1つのリストをTableViewに表示するだけであればrx_itemsWi…

SwiftLint

Swiftでコーディング規約に沿っているかチェックするツールにSwiftLintというのがあるのでつかってみました。 SwiftLintではコーディング規約としてGithubのSwift style guildeを使っています。 使い方 $ brew install swiftlint XcodeでSwiftLintをかけるプ…

RxSwiftでログイン画面のサンプル実装

ユーザー名とパスワードを規定の文字数以上入力するとログインボタンが有効になるViewControllerをRxSwiftを使って実装してみました。 SwiftBondしか使ったことなく初めてRxSwiftを使ってみた感想としては、RxSwiftのほうが似たようなものがたくさんあり学習…

iOSでSlackのWebSocket疎通まで

やること iOSからSlackのWebSocketを使ってメッセージのやり取りをできる状態にする 事前準備 redirect urlを用意せずにモバイルアプリ単体でアクセストークンを取得するのは無理っぽいのでとりあえずテスト用のを使う テスト用のアクセストークンの取得 htt…

コード行数の測定

Swiftでコード行数を測ろうとツールを探していたらclocというのがよさげでした インストール インストール方法は思ったよりたくさん用意されていてlinux系だけでなく、node.jsやhomebrew, macports用のも用意されていて、WindowsやMac環境でも楽にインストー…

WebP.frameworkの作成方法

libwebpをclone > git clone https://chromium.googlesource.com/webm/libwebp 最新のをcheckout > git checkout 0.4.4 iosbuild.shを実行 > iosbuild.sh iosbuild.shでautomakeがないとか怒られた場合は以下を入れる Command line tools > xcode-select --i…