Skip to content

Instantly share code, notes, and snippets.

View devxoul's full-sized avatar
👨‍💻
Always coding

Jeon Suyeol devxoul

👨‍💻
Always coding
View GitHub Profile
@devxoul
devxoul / UIWebViewBackground.swift
Created July 3, 2018 07:59
Set UIWebView's background color to document body's background color
self.webView.rx.didFinishLoad
.subscribe(onNext: { [weak self] in
guard let `self` = self else { return }
let script = "window.getComputedStyle(document.body).backgroundColor;"
guard let result = self.webView.stringByEvaluatingJavaScript(from: script) else { return }
let optionalComponents = result
.components(separatedBy: "(").safe[1]?
.components(separatedBy: ")").safe[0]?
.components(separatedBy: ",")
.map { $0.trimmingCharacters(in: .whitespaces) }
@devxoul
devxoul / building-funnels-with-google-bigquery.sql
Last active May 28, 2018 15:09
A complete query of <Build Funnels with Google BigQuery> presentation.
#standardSQL
WITH events AS (
SELECT "A" AS user, 100 AS time, "view" AS event
UNION ALL SELECT "B", 200, "click"
UNION ALL SELECT "B", 300, "view"
UNION ALL SELECT "A", 400, "click"
UNION ALL SELECT "A", 500, "click"
UNION ALL SELECT "A", 600, "buy"
),
- func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool
+ func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any?) -> Bool
func testBookmark() {
// 1. 리액터를 준비합니다.
let reactor = MyReactor()
// 2. 리액터에 액션을 전달합니다.
reactor.action.onNext(.toggleBookmarked)
// 3. 리액터의 상태가 변경되는지를 검증합니다.
XCTAssertEqual(reactor.currentState.isBookmarked, true)
}
func testAction_refresh() {
// 1. Stub 리액터를 준비합니다.
let reactor = MyReactor()
reactor.stub.isEnabled = true
// 2. Stub된 리액터를 주입한 뷰를 준비합니다.
let view = MyView()
view.reactor = reactor
// 3. 사용자 인터랙션을 발생시킵니다.
func mutate(action: Action) -> Observable<Mutation> {
switch action {
case .follow:
return UserService.follow()
.map { Mutation.setFollowing(true) }
.catchErrorJustReturn(Mutation.setFollowing(false))
case .unfollow:
return UserService.unfollow()
.map { Mutation.setFollowing(false) }
import ReactorKit
import RxSwift
final class UserViewReactor: Reactor {
enum Action {
case follow
}
enum Mutation {
case setFollowing(Bool)
func bind(reactor: UserViewReactor) {
// Action
self.followButton.rx.tap
.map { Reactor.Action.follow }
.bind(to: reactor.action)
.disposed(by: self.disposeBag)
// State
reactor.state.map { $0.isFollowing }
.distinctUntilChanged()
import ReactorKit
import RxSwift
class UserViewController: UIViewController, View {
var disposeBag = DisposeBag()
func bind(reactor: UserViewReactor) {
}
}
@devxoul
devxoul / filter-codecov-filename.js
Last active March 31, 2018 09:44
Filter codecov by filename
$('#tree tbody tr').each((i, tr) => {
const filename = $(tr).find('td:first a').text();
if (!filename.includes('Reactor.swift')) {
$(tr).remove();
}
});