Skip to content

Instantly share code, notes, and snippets.

Peter Steinberger steipete

View GitHub Profile
@steipete
steipete / PSPDFEnvironment.m
Last active Mar 26, 2019
PSPDFApplicationIsTerminating - detect application termination on iOS and macOS. License: MIT. Taken out of the commercial PSPDFKit PDF SDK. http://pspdfkit.com
View PSPDFEnvironment.m
static _Atomic(BOOL) _applicationWillTerminate = NO;
__attribute__((constructor)) static void PSPDFInstallAppWillTerminateHandler(void) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[NSNotificationCenter.defaultCenter addObserverForName:UIApplicationWillTerminateNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
_applicationWillTerminate = YES;
PSPDFLogWarning(@"Application shutdown event detected.");
}];
});
}
View UndoManagerWorkaround.swift
extension UndoManager {
@objc func workaround_pspdf_endUndoGrouping() {
guard self.groupingLevel > 0 else { return }
self.workaround_pspdf_endUndoGrouping()
}
// Ensure this is only called once!
fileprivate static func InstallWorkaroundForRdar46395110() {
let originalSelector = #selector(UndoManager.endUndoGrouping)
let swizzledSelector = #selector(UndoManager.workaround_pspdf_endUndoGrouping)
@steipete
steipete / TempDir.swift
Created Oct 25, 2018
Based on https://nshipster.com/temporary-files/ I ran some experiments with the recommended replacement API for NSTemporaryDirectory(). It's not straightforward.
View TempDir.swift
// tl;dr: FileManager.default.url(for:in:appropriateFor:create:) has unexpected behavior in Simulator and creates temporary folders outside the tmp/ directory.
let tmpDirClassic = NSTemporaryDirectory()
print("tmpDirClassic: \(tmpDirClassic)")
// This is the same code, just syntax sugar for NSTemporaryDirectory()
// https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/FileManager.swift#L1420-L1422
let tmpDirClassicNewShim = FileManager.default.temporaryDirectory
print("tmpDirClassicNewShim: \(tmpDirClassicNewShim)")
// Simulator: /Users/steipete/Library/Developer/CoreSimulator/Devices/31C05637-B9C9-482C-A6CE-D063A7CECF64/data/Containers/Data/Application/A68D11A4-88BA-4FCF-A8B1-D102945D0740/tmp/
View UIKit+iOSMac.h
#import <Foundation/Foundation.h>
@class NSString, UHASToolbarItem;
__attribute__((weak_import)) @interface _UIWindowToolbarItem : NSObject
@property(readonly, copy, nonatomic) NSString *label;
@property(readonly, copy, nonatomic) NSString *identifier;
- (id)initWithIdentifier:(id)arg1;
@steipete
steipete / TestCaseSubclass.m
Last active Dec 5, 2018
If you get an [NSProxy doesNotRecognizeSelector:_accessibilityLoadAccessibilityInformation] crash in iOS 12, here's a temporary fix for your tests. Please change the prefix before you use this! MIT licensed.
View TestCaseSubclass.m
static void PSPDFFixiOS12AccessibilityTestCrash(void) {
let accessibilityLoaderClass = NSClassFromString(@"UIAccessibilityInformationLoader");
let accessibilitySEL = NSSelectorFromString(@"_loadAccessibilityInformationOnMainThread:");
__block IMP originalIMP = pspdf_swizzleSelectorWithBlock(accessibilityLoaderClass, accessibilitySEL, ^(id _self, BOOL onMainThread) {
@try {
((void (*)(id, SEL, BOOL))originalIMP)(_self, accessibilitySEL, onMainThread);
} @catch (NSException *exception) {
NSLog(@"Exception received: %@", exception);
if ([exception.name isEqualToString:NSInvalidArgumentException] && [exception.reason containsString:@"_accessibilityLoadAccessibilityInformation"]) {
NSLog(@"Ignoring IOS 12b5 weirdness...");
View Confused.m
// Works
__auto_type queue = dispatch_queue_create("com.pspdfkit.test", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(queue, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0));
// Crashes with EXC_BAD_INSTRUCTION
// I guess this fails because the global queues already have an autorelease pool?
__auto_type queue2 = dispatch_queue_create("com.pspdfkit.test", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL);
dispatch_set_target_queue(queue2, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0));
View gist:a759b56dc1b5d94ba5b3c03ddd00a1ed
Process: Tweetbot [58303]
Path: /Applications/Tweetbot.app/Contents/MacOS/Tweetbot
Identifier: com.tapbots.TweetbotMac
Version: 2.5.4 (25400)
App Item ID: 557168941
App External ID: 824334033
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: Tweetbot [58303]
User ID: 501
@steipete
steipete / DispatchQueueSurprise.m
Last active Dec 21, 2018
This fails in iOS 9, but passes for iOS 10/11. What changed around serial/concurrent dispatch queues in iOS 10 so that this now works. Or rather, why does this not work in iOS 9?
View DispatchQueueSurprise.m
- (void)testDispatchConcurrentExecutionWithNamedQueuesRaw {
let expectation = [self expectationWithDescription:@"Concurrent execution must happen"];
let semaphore = dispatch_semaphore_create(0);
// global queue, concurrent
let attributes = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, 0);
let defaultQueue = dispatch_queue_create("com.pspdfkit.default-concurrent", attributes);
// serial sub-queues that dispatch to concurrent queue
let queue1 = dispatch_queue_create("com.pspdfkit.queue1", DISPATCH_QUEUE_SERIAL);
@steipete
steipete / gist:8c683dd840596e34dcb9159373cea933
Created Nov 8, 2017
NSObject is overloaded. This is iOS 11.2b2. Crazy. And yes, `pspdf` is guilty as well. It's so easy/convenient to make a category on it.
View gist:8c683dd840596e34dcb9159373cea933
Class Methods:
+ (Class) safeCategoryBaseClass; (0x12c470134)
+ (BOOL) _old_unswizzled_automaticallyNotifiesObserversForKey:(id)arg1; (0x1150df5a0)
+ (id) _old_unswizzled_keyPathsForValuesAffectingValueForKey:(id)arg1; (0x1150df620)
+ (id) requiredStoreLibraryPersonalizationProperties; (0x118daaeff)
+ (void) mf_clearLocks; (0x11a41d09e)
+ (void) _accessibilityCalDetailStringForEvent:(id)arg1 inLine1:(id*)arg2 inLine2:(id*)arg3 inLine3:(id*)arg4 inLine4:(id*)arg5; (0x127db7c6e)
+ (void) _accessibilityCalGetHourDesignatorsForAM:(id*)arg1 andPM:(id*)arg2; (0x127d1e7bb)
+ (BOOL) _accessibilityCalSpaceBetweenDesignatorsAndHour; (0x127d1e7cb)
+ (BOOL) _accessibilityCalHourDesignatorsAreBeforeHour; (0x127d1e7ec)
@steipete
steipete / gist:2ec99bca9dd01e405f9fd7db17472cb5
Created Oct 31, 2017
Crash in com.apple.dt.async-test-expectation
View gist:2ec99bca9dd01e405f9fd7db17472cb5
Process: PSPDFFoundation-TestHost-iOS [95495]
Path: /Users/USER/Library/Developer/CoreSimulator/Devices/1694A397-7C29-4470-A3A0-9A3E350DB19E/data/Containers/Bundle/Application/3A6309AC-3045-4D7C-9E83-006339C933C6/PSPDFFoundation-TestHost-iOS.app/PSPDFFoundation-TestHost-iOS
Identifier: PSPDFFoundation-TestHost-iOS
Version: 1.0 (1)
Code Type: X86-64 (Native)
Parent Process: launchd_sim [93146]
Responsible: PSPDFFoundation-TestHost-iOS [95495]
User ID: 502
Date/Time: 2017-10-30 15:37:04.800 -0400
You can’t perform that action at this time.