iOS 13 でカスタム UTI のファイルが開けない

アプリ間連携によるファイルの受け取りが iOS 13 でのみカスタム UTI のファイルが開けなくなってしまいました。

任意の拡張子を持つファイルをアプリで受け取る方法はこちらの記事が参考になります。

[iOS] Info.plistにカスタムUTIを追加し、iOSがデフォルトで認識できないタイプのファイルを受け取れるようにする

同様のことが他にも起きているようでした。

App unable to import files in iOS13

解決方法

上記のフォーラムで「public.data を継承させる必要がある」的な事が書かれていたのでそのとおりにしたこところ修正できました。

「入門 ReactiveSwift 」という発表をした

社内勉強会で「入門 ReactiveSwift」というタイトルで発表をしました。
↓スライド資料です。

なんと 191 ページもあります。

ReactiveSwift はまだまだ日本語の資料が少ないですからせっかくなので公開しました。
もっと使う人が増えればいいのですが…。

機会があれば ReactiveCocoa のことにも触れたり実践的な内容を取り扱ったりしたいです。

ちなみに発表時間は 50 分でした。
くちパッサパサになりましたよ。

Bitrise で XCTest がコケる

Bitrise でビルドは通るけど XCTest がコケるのを直した話を書きます。

encountered an error (Early unexpected exit, operation never finished bootstrapping - no restart will be attempted. Underlying error: Test runner exited before starting test execution.)

こういうエラーが出て困っていました。

結論

Bitrise 上の Carthage のバージョンが古く xcfilelist に対応していなかったが最新版に更新したら直った。

続きを読む

ReactiveSwift と APIKit を組み合わせる

今日は ReactiveSwiftAPIKit を組み合わせてみます。

いきなりですが以下のようなコードになります。

extension Session: ReactiveExtensionsProvider { }

extension Reactive where Base: Session {
    
    func send<Request>(_ request: Request) -> SignalProducer<Request.Response, SessionTaskError> where Request: APIKit.Request {
        return SignalProducer { [weak base] observer, lifetime in
            guard let session = base else {
                observer.sendInterrupted()
                return
            }
            
            let task = session.send(request) { result in
                switch result {
                case .success(let response):
                    observer.send(value: response)
                    observer.sendCompleted()
                case .failure(let sessionTaskError):
                    observer.send(error: sessionTaskError)
                }
            }
            
            lifetime.observeEnded {
                task?.cancel()
            }
        }
    }
}

let request = AppRequest(name: "おとなのおこづかい帳")
Session.shared.reactive.send(request).startWithResult { result in
    switch result {
    case .success(let app):
        print(app.review == "★★★★★")
    case .failure(let sessionTaskError):
        print(sessionTaskError)
    }
}

RxSwift 版を参考にしました。

ReactiveSwift にはエラーの型が指定できるので RxSwift とくらべてエラーハンドリングしやすそうですね。

// RxSwift
func send<Request>(_ request: Request) -> Observable<Request.Response>

// ReactiveSwift
func send<Request>(_ request: Request) -> SignalProducer<Request.Response, SessionTaskError>

ReactiveSwift もいいぞという話

Swift のリアクティブプログラミングのライブラリといえば RxSwiftReactiveSwift が有名ですよね。

今まで RxSwift しか使ってこなかったのですが ReactiveSwift を使ってみたらとても良かったのでそれについて書きたいと思います。

ReactiveSwift と RxSwift を比較する形で紹介します。

RxSwift やその他 Rx ライブラリをある程度自由に使いこなせるという方を対象に書いています。

続きを読む

Carthage で SwiftDate を更新したらエラー “Task failed with exit code 65:” が発生する

環境

Version
Xcode 9.2
Carthage 0.29.0
SwiftDate 4.5.1

Carthage 経由でインストールしていた SwiftDate を 4.5.1 へ更新したときに以下のようなエラーが起きました。

*** Building scheme "SwiftDate-iOS" in SwiftDate.xcodeproj
*** Building scheme "SwiftDate" in SwiftDate.xcodeproj
Build Failed
Task failed with exit code 65:
/usr/bin/xcrun xcodebuild -project ...

This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: ...

続きを読む