Skip to content

Instantly share code, notes, and snippets.

View banjun's full-sized avatar

banjun banjun

View GitHub Profile
@banjun
banjun / MultiColumnText.swift
Last active May 2, 2024 07:53
SwiftUI multi column text backed by TextKit 1 multi column layout
struct MultiColumnText: View {
private let storage: NSTextStorage
private let layoutManager: NSLayoutManager = .init()
private let containers: [NSTextContainer]
init(text: NSAttributedString, columns: Int) {
storage = .init(attributedString: text)
storage.addLayoutManager(layoutManager)
containers = (0..<columns).map {_ in .init()}
containers.forEach {
@banjun
banjun / beaconcapture.swift
Created January 24, 2019 05:35
Capture iBeacon packets and show them in Touch Bar
#!/usr/bin/swift
import CoreBluetooth
import AppKit
class AppDelegate: NSResponder, CBCentralManagerDelegate, NSTouchBarDelegate, NSApplicationDelegate {
let manager: CBCentralManager
var advertises: [Advertise] = []
override init() {
manager = CBCentralManager(delegate: nil, queue: DispatchQueue.main)
@banjun
banjun / Inwardbox.swift
Created April 16, 2024 05:19
for visionOS gestures, generate a box with its surfaces facing inward
import RealityKit
extension ShapeResource {
/// generate a box with its surfaces facing inward.
/// NOTE: size 30 works with interactions, 50 does not work with interactions
static func generateInwardBox(size: Float) async throws -> ShapeResource {
// An array of vertex positions containing discrete points on the mesh.
let meshPositions: [SIMD3<Float>] = [
.init(-1, -1, -1), // 0 LBF
.init(+1, -1, -1), // 1 RBF
@banjun
banjun / UserActivityWindowGroup.swift
Last active March 19, 2024 16:49
Open new window on drop UserActivity
import SwiftUI
// prerequisites in Info.plist: NSUserActivityTypes contains type, UIApplicationSceneManifest/UIApplicationSupportsMultipleScenes = YES
// accepts NSUserActivity.targetContentIdentifier = type
// see also: https://developer.apple.com/documentation/swiftui/scene/handlesexternalevents(matching:)
struct UserActivityWindowGroup<Content: View, Payload: Codable>: Scene {
var type: String
@ViewBuilder var content: (Payload) -> Content
init(type: String, payloadType: Payload.Type, @ViewBuilder content: @escaping (Payload) -> Content) {
@banjun
banjun / WindowCapture.swift
Last active January 31, 2024 18:44
specific window capture implementation memo for https://github.com/mzp/HeartVoice
import Cocoa
import CoreGraphics
import Vision
struct TargetWindow {
let id: CGWindowID
let bounds: CGRect
init?(appName: String, windowTitle: String) {
guard let windows = CGWindowListCopyWindowInfo(.optionAll, kCGNullWindowID) as? [[String: Any]] else { return nil }
@banjun
banjun / convert-lib-fw-to-sim-device-universal-xcfw.sh
Last active October 30, 2023 07:28
create an xcframework from a universal static lib .a or universal static .framework without rebuild
#!/bin/zsh
if [[ -z $BOGO_ARM64_TO_SIM ]]; then
echo "❌ requires BOGO_ARM64_TO_SIM: set an executable binary path built from https://github.com/bogo/arm64-to-sim"
exit 1;
fi
set -eu
# set -x # debug log
@banjun
banjun / MockAVCaptureDevice.swift
Last active July 13, 2023 14:53
mock AVCaptureDevice in Xcode 9
extension AVCaptureDevice {
class func swizzle() {
[(#selector(AVCaptureDevice.defaultDevice(withMediaType:)), #selector(AVCaptureDevice.mockDefaultDevice(withMediaType:)))].forEach {
let original = class_getClassMethod(self, $0)
let mock = class_getClassMethod(self, $1)
method_exchangeImplementations(original, mock)
}
[(#selector(AVCaptureDevice.hasMediaType(_:)), #selector(AVCaptureDevice.mockHasMediaType(_:))),
(#selector(AVCaptureDevice.supportsAVCaptureSessionPreset(_:)), #selector(AVCaptureDevice.mockSupportsAVCaptureSessionPreset)),
(#selector(AVCaptureDevice.isTorchModeSupported(_:)), #selector(AVCaptureDevice.mockIsTorchModeSupported)),
@banjun
banjun / BlackHoleAVCaptureAudioPreviewOutput.swift
Created April 18, 2020 17:50
Set AVCaptureSession output to BlackHole or another arbitrary device by an output device name
private let audioOutput: AVCaptureAudioPreviewOutput = {
let audioOutput = AVCaptureAudioPreviewOutput()
audioOutput.volume = UserDefaults.standard.volume
struct Device {
var name: String?
var uid: String?
}
var devicesProperty = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDevices, mScope: kAudioDevicePropertyScopeOutput, mElement: kAudioObjectPropertyElementWildcard)
var devicesSize: UInt32 = 0
@banjun
banjun / ViewController.swift
Created November 3, 2017 03:43
list AVCaptureDevice including iOSScreenCaptureAssistant
import Cocoa
import CoreMediaIO
import AVFoundation
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
var prop = CMIOObjectPropertyAddress(
mSelector: CMIOObjectPropertySelector(kCMIOHardwarePropertyAllowScreenCaptureDevices),
@banjun
banjun / main.swift
Created February 14, 2017 07:36
add Touch Bar support for CLI without .app bundle nor Info.plist
class AppDelegate: NSResponder, NSTouchBarDelegate, NSApplicationDelegate {
@available(OSX 10.12.2, *)
lazy var touchbar: NSTouchBar = {
let tb = NSTouchBar()
tb.delegate = self
tb.defaultItemIdentifiers = [NSTouchBarItemIdentifier(rawValue: "test")]
return tb
}()