Skip to content

Instantly share code, notes, and snippets.

View samsonjs's full-sized avatar

Sami Samhuri samsonjs

View GitHub Profile
@samsonjs
samsonjs / SendableWrapper.swift
Last active February 25, 2025 01:00
See https://github.com/samsonjs/SJSAssetExportSession — Exporting videos with AVFoundation in the strict concurrency world of Swift 6
//
// Created by Sami Samhuri on 2024-06-26.
//
import Foundation
final class SendableWrapper<T>: @unchecked Sendable {
private var unsafeValue: T
private let lock = NSLock()
@samsonjs
samsonjs / Tracks.swift
Last active June 24, 2024 15:20
FB14035001: Tracks loaded from an AVAsset should be marked `sending` to be used from actor-isolated contexts
import AVFoundation
/*
* In Swift 6 it’s not currently possible to directly load tracks from an AVAsset using a method like
* AVAsset.loadTracks(withMediaType:) from an actor-isolated context, because AVAssetTrack isn’t Sendable. Given
* that many AVFoundation types are not sendable / thread-safe it’s tempting to use an actor to work with
* compositions and that currently requires some work-arounds that shouldn’t be necessary and may not be obvious
* to everyone.
*/
@samsonjs
samsonjs / SendableWrapper.swift
Last active June 22, 2024 16:46
SyncState isolation example
final class SendableWrapper<T>: @unchecked Sendable {
private var unsafeValue: T
private let lock = NSLock()
var value: T {
get {
lock.withLock { unsafeValue }
}
set {
@samsonjs
samsonjs / MovieExporter.swift
Created June 21, 2024 15:15
AVAssetExportSession safety when using structured concurrency in Swift 5 and 6
import AVFoundation
/**
* AVAssetExportSession is initialized with an AVComposition, and that composition and all of its constituent
* components are not sendable. Because `composition` is isolated to the main actor here, the call to the
* non-isolated method `export(to:as:)` sends it across an isolation region and that is unsafe.
*/
@MainActor
class UnsafeMovieExporter {
let composition = AVMutableComposition()
@samsonjs
samsonjs / MovieExportSession.swift
Created June 21, 2024 05:39
Weird AVAssetExportSession sendable error in Swift 6
import AVFoundation
import Combine
import OSLog
private let log = Logger.forType(MovieExportSession.self)
actor MovieExportSession {
let composition: AVComposition
let audioMix: AVAudioMix?
@samsonjs
samsonjs / honeybadger_logger.rb
Last active June 11, 2024 16:45
Honeybadger logger for Ruby on Rails
require 'json'
require 'logger'
require 'net/http'
require 'stringio'
require 'zlib'
module Pronto
# Logs messages to Honeybadger's events API (Insights). The logger buffers messages and sends
# them to the API in batches. The logs are currently not structured and are sent as plain text,
# but if/when we actually move off of Papertrail then we can consider sending structured logs as
@samsonjs
samsonjs / anonymizer.rb
Created May 21, 2024 16:48 — forked from TALlama/anonymizer.rb
This class will use your existing FactoryBot factories to rewrite the data already in the db, keeping the associations and structure but replacing the content.
class Anonymizer
include ActiveSupport::Benchmarkable
attr_reader :factory_names, :callbacks
def initialize(factory_names = nil, callbacks = {})
raise ArgumentError.new("You must be in development to use the anonymizer") unless Rails.env.development?
require Rails.root.join("spec/factories") unless FactoryBot.factories.count > 0
@factory_names = [*factory_names].compact.map(&:to_sym)
@samsonjs
samsonjs / LogEvent.swift
Created April 23, 2024 00:01
Log info about an event titled "View recent photos"
import EventKit
import Foundation
import ObjectiveC.runtime
func logIvarList(obj: NSObject) {
var count: UInt32 = 0
if let ivars = class_copyIvarList(type(of: obj), &count) {
for i in 0..<Int(count) {
let ivar = ivars[i]
let name = ivar_getName(ivar).map(String.init(cString:)) ?? "Unknown"
@samsonjs
samsonjs / photos-navigation-url-candidates.txt
Last active April 19, 2024 03:05
Flailing trying to find out how to open Photos.app (aka MobileSlideShow.app) to a specific asset like the Photo Shuffle lock screen
Decompiling the binary and looking through the methods `-[PhotosWindowSceneDelegate openRoutingURL:]`
and `-[PhotosURLNavigationRequest _navigateAllowingRetry:]` uncovers some candidates:
- photos-navigation://asset?uuid={uuid}
- photos-navigation://album?name=recents&revealassetuuid={uuid}
- photos-navigation://contentmode?id=photos&assetuuid={uuid}&oneUp=1
Opening up an album by name works but so far I've had no luck figuring out how to show a specific asset.
And ideally it would open up in the photo library tab not the albums tab, just like the Photo Shuffle
lock screen.
@samsonjs
samsonjs / AssetFetcher.swift
Created April 18, 2024 21:17
Fetching assets from the photo library
//
// AssetFetcher.swift
// DailyDrip
//
// Created by Sami Samhuri on 2022-11-06.
//
import Foundation
import Photos