Skip to content

Instantly share code, notes, and snippets.

View jordanebelanger's full-sized avatar
🚊

Jordane Belanger jordanebelanger

🚊
  • Montreal, Quebec
View GitHub Profile
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (scrollView.scrollDirectionX == ScrollDirectionRight) {
//Do something with your views etc
}
if (scrollView.scrollDirectionY == ScrollDirectionUp) {
//Do something with your views etc
}
}
@jordanebelanger
jordanebelanger / Single+Result.swift
Created June 7, 2018 20:07
Generically create an RxSwift Single observable from any Alamofire's Result type based asynchronous callback function.
import RxSwift
import Alamofire
extension Single {
static func make<T>(from resultFn: @escaping (@escaping (Result<T>) -> Void) -> Void) -> Single<T> {
return Single<T>.create { sub in
resultFn { result in
switch result {
case .success(let value):
sub(SingleEvent.success(value))
import Foundation
enum Nullable<Value: Codable>: Codable {
case some(_ value: Value)
case null
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if container.decodeNil() {
self = .null
@jordanebelanger
jordanebelanger / LoggingSystem+StackdriverLogging.swift
Last active June 15, 2020 14:56
Bootstrapping StackdriverLogging in a Vapor 4 application, the `LoggingSystem+StackdriverLogging.swift` file should go in your App target
import Vapor
import StackdriverLogging
extension LoggingSystem {
/// Prepare the `StackdriverLogHandlerFactory` and bootstrap the `LoggingSystem` to use `StackdriverLogHandler`s.
///
/// - Returns: A `StackdriverLoggerLifecycleHandler` that must be passed to the `Vapor.Application` `lifecyle` service
/// for proper shutdown of the NIO dependencies used by the logger when the `Application` shuts down.
public static func bootstrapStackdriverLogging(for environment: inout Environment,
with configuration: StackdriverLoggingConfiguration) throws -> StackdriverLoggerLifecycleHandler {
import NIO
import Logging
extension EventLoopFuture {
func whenFailureLog(
level: Logger.Level = .error,
_ message: @escaping @autoclosure () -> Logger.Message,
using logger: Logger,
errorDescriptionMetadataKey: String = "reason",
metadata: @escaping @autoclosure () -> Logger.Metadata? = nil,
/// Raw representable `Codable` property wrapper used to instantiate to a `RawRepresentable` type if the `rawValue`decoded is supported
/// by the generic `RawRepresentableValue` type. This can be useful when you want to decode a set of constant values
/// specified inside `RawRepresentable` enum yet default to the `rawValue` if the decoded `rawValue` is unsupported.
///
/// For example, using this property wrapper you could decode an enum specifying a list of error code such as:
///
/// enum ErrorCode: String, Codable {
/// case notFound, unauthorized, badRequest
/// }
///
import class Dispatch.DispatchQueue
import NIO
public extension DispatchQueue {
/// `DispatchQueue.async` but returning a NIO future wrapping the closure return.
func async<Value>(on eventLoop: EventLoop, use closure: @escaping () throws -> Value) -> EventLoopFuture<Value> {
let promise = eventLoop.makePromise(of: Value.self)
async {
do {
promise.succeed(try closure())
@jordanebelanger
jordanebelanger / Nullable.swift
Last active March 29, 2021 00:04
Codable enum that will differentiate between an explicitly null value vs the value being missing, useful for PATCH request etc
enum Nullable<T>: Codable where T: Codable {
case some(_ value: T)
case null
case undefined
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if container.decodeNil() {
self = .null
} else {
@jordanebelanger
jordanebelanger / bytebuffer-serialization.swift
Last active January 21, 2021 15:44
Manually encode and decode a codable type to and from a bytebuffer for redis usage
import Vapor
import RedisKit
struct MySession {
let token: RedisKey
let email: String
let userId: Int64
let isAdmin: Bool
let ipAddress: String?
public struct ResultCodable<CodableType>: Codable where CodableType: Codable {
private enum EncodingError: Swift.Error, CustomStringConvertible {
case encodedErrorResult(encodingError: Swift.Error)
var description: String {
switch self {
case .encodedErrorResult(let encodingError):
return "Cannot encode `Result.failure` which resulted from decoding error: '\(encodingError)'"
}