Skip to content

Instantly share code, notes, and snippets.

Thongchai Kolyutsakul hlung

Block or report user

Report or block hlung

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
View Fastlane podspec version utils.rb
lane :replace_podspec_version do |options|
# Input file (content) => "s.version = '0.1.0'"
# Input new_version => "0.2.0"
# Output file (content) => "s.version = '0.2.0'"
# Note: For debugging, you can remove -i to make it print output to console without editing file in place.
# Somehow backup file *.bak has to be created for edit in-place (-i) option, otherwise sed command will fail.
sh("cd ..; sed -i bk \"s/\\(s.version.*['\\\"]\\).*\\(['\\\"]\\)/\\1#{options[:new_version]}\\2/g\" #{options[:file]}")
lane :get_podspec_version do |options|
View SoompiBlog - Layout Driven UI example.swift
class ArticleView: UIView {
var totalCommentCount: Int = 0 {
didSet {
var hasComment: Bool = false {
didSet {
View SoompiBlog - DiscoverCategoryFetcher.swift
import Foundation
final class DiscoverCategoryFetcher: PagedResponseFetcher<PaginationParameter, DiscoverCategoryResponse, DiscoverCategory> {
View SoompiBlog - Pageable & PagedResponse.swift
import Foundation
protocol Pageable {
/// Moves the receiver's value to next set
mutating func next(cursor: String?)
// Represents a paged response from API.
protocol PagedResponse {
associatedtype Element
View SoompiBlog - SimplifiedPagedResponseFetcher.swift
import Foundation
import RxSwift
import RxCocoa
class SimplifiedPagedResponseFetcher<LoaderInput, LoaderOutput>
where LoaderInput: Pageable, LoaderOutput: PagedResponse {
/// The main actor here 🤘. Sends all the Elements currently available.
let elementsRelay = BehaviorRelay<[LoaderOutput.Element]>(value: [])
lazy var elements: Driver<[LoaderOutput.Element]> = { return elementsRelay.asDriver() }()
View SoompiBlog - AppCoordinator+Perform.swift
@discardableResult func perform(_ navigation: Navigation) -> Bool {
guard let navigationController = currentNavigationController() else { return false }
// Check first if we can perform the navigation.
let currentNavigation = (navigationController.visibleViewController as? NavigationSource)?.sourceNavigation
let nextNavigation = navigation.redirectIfNeeded(from: currentNavigation)
switch nextNavigation {
case .tab(let tabType):
for viewController in tabBarController.viewControllers ?? [] {
View SoompiBlog - Navigation.swift
import Foundation
import UIKit
/// A model representing a navigation destination.
indirect enum Navigation {
case tab(type: TabType)
case post(id: String, partialPost: PartialPost?, fetcher: FeedFetcher?)
case feed(parameter: FeedParameter)
case safari(url: URL)
case applicationOpen(url: URL)
View SoompiBlog - Reload Example.swift
class FeedViewController: BaseViewController {
override func viewDidLoad() {
View SoompiBlog - Reversible.swift
import Foundation
protocol Reversible {
var isOn: Bool { get set }
mutating func reverse()
func reversed() -> Self
extension Reversible {
View SoompiBlog - Reaction.swift
/// Represents a user action which reacts to something
struct Reaction {
let type: ReactionType
let target: ReactionTarget
var isOn: Bool
enum ReactionType: String, Decodable {
case heart
case unsupported
You can’t perform that action at this time.