Skip to content

Instantly share code, notes, and snippets.

@lipka
lipka / Throttle.swift
Last active September 1, 2023 21:44
Limits the rate at which a closure is executed by preventing it's execution until a specified amount of time has elapsed.
import Foundation
/**
Limits the rate at which a closure is executed by preventing it's execution until a specified amount of time has elapsed.
Example:
```
let fetchThrottle = Throttle(interval: 60)
fetchThrottle {
@lipka
lipka / Cache.swift
Last active November 26, 2023 00:50
A first-class type-safe Swift cache based on NSCache with support for value types as keys.
import Foundation
// Based on https://www.swiftbysundell.com/articles/caching-in-swift/
final class Cache<Key: Hashable, Value> {
private let wrapped = NSCache<WrappedKey, Entry>()
func insert(_ value: Value, forKey key: Key) {
let entry = Entry(value: value)
wrapped.setObject(entry, forKey: WrappedKey(key))
@lipka
lipka / SafeTask.swift
Last active August 13, 2023 15:10
Force error handling in for Swift's Task when using structured concurrency.
// Swift's `Task` silently discards errors from throwable callsites. `SafeTask` forces you to explicitly handle errors at the callsite and helps you avoid mistakes with silently discarded errors.
@discardableResult func SafeTask<Success>(priority: TaskPriority? = nil, operation: @escaping () async -> Success) -> Task<Success, Never> where Success: Sendable {
return Task(priority: priority, operation: {
await operation()
})
}
@lipka
lipka / Buildkite + Fastlane CI
Last active November 7, 2018 15:41
Tink's Buildkite and Fastlane setup for CI/CD
1. Install Xcode (available in the Mac App Store)
2. Install [Brew](https://brew.sh)
3. Install [Cocoapods](https://cocoapods.org)
4. Install [Fastlane](https://docs.fastlane.tools)
5. In Xcode, make sure that under Preferences/Locations the Command Line Tools field is not empty
6. Add provisoning profiles and certificates
7. Install [Buildkite agent](https://buildkite.com/docs/agent/v3/osx)
* `brew tap buildkite/buildkite`
* `brew install --token='INSERT-YOUR-AGENT-TOKEN-HERE' buildkite-agent`
* Run `brew info buildkite-agent` and execute the command displayed at the end to autostart the agent
@lipka
lipka / CGRectAspectFit.m
Created November 9, 2017 22:08 — forked from lanephillips/CGRectAspectFit.m
Objective-C code to fit a CGRect inside or outside another CGRect while maintaining aspect ratio. The fitted rectangle is centered on the target rectangle.
CGFloat ScaleToAspectFitRectInRect(CGRect rfit, CGRect rtarget)
{
// first try to match width
CGFloat s = CGRectGetWidth(rtarget) / CGRectGetWidth(rfit);
// if we scale the height to make the widths equal, does it still fit?
if (CGRectGetHeight(rfit) * s <= CGRectGetHeight(rtarget)) {
return s;
}
// no, match height instead
return CGRectGetHeight(rtarget) / CGRectGetHeight(rfit);
import UIKit
// This class allows the "presentedController" to receive touches
// https://pspdfkit.com/blog/2015/presentation-controllers/
class PSPDFTouchForwardingView: UIView {
var passthroughViews: [UIView] = []
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
guard let hitView = super.hitTest(point, withEvent: event) else { return nil }
// Created by Caleb Davenport on 7/14/17.
import UIKit
final class ActionSheetPresentationController: UIPresentationController {
// MARK: - Properties
private var dimmingView: UIView!
@lipka
lipka / gist:891a274b47b2877e8ce434e4d215898c
Created July 9, 2017 12:36 — forked from steipete/ios-xcode-device-support.sh
Using iOS 10.3 devices with Xcode 8.2.1
// The trick is to link the DeviceSupport folder from the beta to the stable version.
// Updated on Jan 24th, 2017 for Xcode 8.3b1
ln -s /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/10.3\ \(14E5230d\)/ /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport
// Then restart Xcode and reconnect your devices. You will need to do that for every beta of future iOS versions
// sudo needed if you run the Mac App Store version. Always download the dmg instead... you'll thank me later :)
@lipka
lipka / TabComponent.swift
Created August 11, 2016 21:33 — forked from irace/TabComponent.swift
Easily roll your own `UITabBarController` alternatives. Here’s all the logic you need without assuming anything about your UI.
/**
* A class that can be part of a tabbed navigational interface (expected to be a `UIViewController` but can also be a
* coordinator that proxies through to an underlying controller).
*/
public protocol TabComponent {
/// The tab metadata
var tabItem: TabItem { get }
var viewController: UIViewController { get }
}
@lipka
lipka / PSPDFUIKitMainThreadGuard.m
Created April 26, 2016 22:43 — forked from steipete/PSPDFUIKitMainThreadGuard.m
This is a guard that tracks down UIKit access on threads other than main. This snippet is taken from the commercial iOS PDF framework http://pspdfkit.com, but relicensed under MIT. Works because a lot of calls internally call setNeedsDisplay or setNeedsLayout. Won't catch everything, but it's very lightweight and usually does the job.You might n…
// Taken from the commercial iOS PDF framework http://pspdfkit.com.
// Copyright (c) 2014 Peter Steinberger, PSPDFKit GmbH. All rights reserved.
// Licensed under MIT (http://opensource.org/licenses/MIT)
//
// You should only use this in debug builds. It doesn't use private API, but I wouldn't ship it.
#import <objc/runtime.h>
#import <objc/message.h>
// Compile-time selector checks.