Skip to content

Commit

Permalink
Allow use without AppKit
Browse files Browse the repository at this point in the history
  • Loading branch information
nickdowell committed Apr 14, 2021
1 parent 5a00246 commit d810ca8
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 7 deletions.
8 changes: 8 additions & 0 deletions Bugsnag.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@
01840B7425DC26E200F95648 /* BSGEventUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 01840B6E25DC26E200F95648 /* BSGEventUploader.m */; };
01840B7525DC26E200F95648 /* BSGEventUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 01840B6E25DC26E200F95648 /* BSGEventUploader.m */; };
0187D464255BD7B800C503D9 /* BugsnagApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9103632502320A00E9D1E2 /* BugsnagApiClientTest.m */; };
019480D42625F3EB00E833ED /* BSGAppKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 019480D32625F3EB00E833ED /* BSGAppKitTests.m */; };
01B14C56251CE55F00118748 /* report-react-native-promise-rejection.json in Resources */ = {isa = PBXBuildFile; fileRef = 01B14C55251CE55F00118748 /* report-react-native-promise-rejection.json */; };
01B14C57251CE55F00118748 /* report-react-native-promise-rejection.json in Resources */ = {isa = PBXBuildFile; fileRef = 01B14C55251CE55F00118748 /* report-react-native-promise-rejection.json */; };
01B14C58251CE55F00118748 /* report-react-native-promise-rejection.json in Resources */ = {isa = PBXBuildFile; fileRef = 01B14C55251CE55F00118748 /* report-react-native-promise-rejection.json */; };
Expand Down Expand Up @@ -1323,6 +1324,8 @@
01937D09257A7ED000F2DE31 /* BugsnagSessionTracker+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagSessionTracker+Private.h"; sourceTree = "<group>"; };
01937D11257A814D00F2DE31 /* BugsnagMetadata+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagMetadata+Private.h"; sourceTree = "<group>"; };
01937D2E257A83A900F2DE31 /* BugsnagApp+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagApp+Private.h"; sourceTree = "<group>"; };
019480C42625EE9800E833ED /* BSGAppKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BSGAppKit.h; sourceTree = "<group>"; };
019480D32625F3EB00E833ED /* BSGAppKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BSGAppKitTests.m; sourceTree = "<group>"; };
0195FC3B256BC81400DE6646 /* BugsnagEvent+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagEvent+Private.h"; sourceTree = "<group>"; };
0198762E2567D5AB000A7AF3 /* BugsnagStackframe+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagStackframe+Private.h"; sourceTree = "<group>"; };
01B14C55251CE55F00118748 /* report-react-native-promise-rejection.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "report-react-native-promise-rejection.json"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1699,6 +1702,7 @@
00AD1C7F24869B0E00A27979 /* Tests */ = {
isa = PBXGroup;
children = (
019480D32625F3EB00E833ED /* BSGAppKitTests.m */,
00896A3F2486DBDD00DC48C2 /* BSGConfigurationBuilderTests.m */,
008966C62486D43600DC48C2 /* BSGConnectivityTest.m */,
01BDB1CE25DEBF4600A91FAF /* BSGEventUploadKSCrashReportOperationTests.m */,
Expand Down Expand Up @@ -1831,6 +1835,7 @@
008969142486DAD000DC48C2 /* BSG_RFC3339DateTool.m */,
010FF28225ED2A8D00E4F2B0 /* BSGAppHangDetector.h */,
010FF28325ED2A8D00E4F2B0 /* BSGAppHangDetector.m */,
019480C42625EE9800E833ED /* BSGAppKit.h */,
CBCF77A125010648004AF22A /* BSGJSONSerialization.h */,
CBCF77A225010648004AF22A /* BSGJSONSerialization.m */,
008968112486DA5600DC48C2 /* BSGSerialization.h */,
Expand Down Expand Up @@ -2838,6 +2843,7 @@
008967132486D43700DC48C2 /* BugsnagEventTests.m in Sources */,
0089675B2486D43700DC48C2 /* BugsnagEnabledBreadcrumbTest.m in Sources */,
008966EC2486D43700DC48C2 /* BugsnagDeviceTest.m in Sources */,
019480D42625F3EB00E833ED /* BSGAppKitTests.m in Sources */,
008967462486D43700DC48C2 /* BugsnagTests.m in Sources */,
008967A62486D43700DC48C2 /* KSString_Tests.m in Sources */,
004E353D2487B3B8007FBAE4 /* BugsnagSwiftTests.swift in Sources */,
Expand Down Expand Up @@ -3406,6 +3412,7 @@
00AD1CBF24869C1200A27979 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_MODULES_AUTOLINK = NO;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
Expand All @@ -3428,6 +3435,7 @@
00AD1CC024869C1200A27979 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_MODULES_AUTOLINK = NO;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
Expand Down
6 changes: 3 additions & 3 deletions Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#if TARGET_OS_IOS || TARGET_OS_TV
#import "BSGUIKit.h"
#else
#import <AppKit/AppKit.h>
#import "BSGAppKit.h"
#endif


Expand All @@ -37,7 +37,7 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration
_configuration = configuration;
_notificationCenter = NSNotificationCenter.defaultCenter;
#if TARGET_OS_OSX
_workspaceNotificationCenter = NSWorkspace.sharedWorkspace.notificationCenter;
_workspaceNotificationCenter = [NSWORKSPACE sharedWorkspace].notificationCenter;
#endif
_breadcrumbSink = breadcrumbSink;
_notificationNameMap = @{
Expand Down Expand Up @@ -277,7 +277,7 @@ - (void)addBreadcrumbForMenuItemNotification:(NSNotification *)notification {
#if TARGET_OS_OSX
NSMenuItem *menuItem = [[notification userInfo] valueForKey:@"MenuItem"];
[self addBreadcrumbWithType:BSGBreadcrumbTypeState forNotificationName:notification.name metadata:
[menuItem isKindOfClass:[NSMenuItem class]] ? @{BSGKeyAction : menuItem.title} : nil];
[menuItem isKindOfClass:NSMENUITEM] ? @{BSGKeyAction : menuItem.title} : nil];
#endif
}

Expand Down
4 changes: 2 additions & 2 deletions Bugsnag/BugsnagSystemState.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#import "BugsnagSystemState.h"

#if TARGET_OS_OSX
#import <AppKit/AppKit.h>
#import "BSGAppKit.h"
#else
#import "BSGUIKit.h"
#endif
Expand Down Expand Up @@ -79,7 +79,7 @@ id blankIfNil(id value) {
bool isActive = true;
#if TARGET_OS_OSX
// MacOS "active" serves the same purpose as "foreground" in iOS
isInForeground = [NSApplication sharedApplication].active;
isInForeground = [NSAPPLICATION sharedApplication].active;
#else
UIApplicationState appState = [BSG_KSSystemInfo currentAppState];
isInForeground = [BSG_KSSystemInfo isInForeground:appState];
Expand Down
2 changes: 1 addition & 1 deletion Bugsnag/Client/BugsnagClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
#if BSG_PLATFORM_IOS
#import "BSGUIKit.h"
#elif BSG_PLATFORM_OSX
#import <AppKit/AppKit.h>
#import "BSGAppKit.h"
#endif

NSString *const BSTabCrash = @"crash";
Expand Down
41 changes: 41 additions & 0 deletions Bugsnag/Helpers/BSGAppKit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// BSGAppKit.h
// Bugsnag
//
// Created by Nick Dowell on 13/04/2021.
// Copyright © 2021 Bugsnag Inc. All rights reserved.
//

#import <AppKit/AppKit.h>

// Daemons and other processes running in non-UI sessions should not link against AppKit.
// These macros exist to allow the use of AppKit without adding a link-time dependency on it.

// Calling code should be prepared for classes to not be found when AppKit is not linked.
#define NSAPPLICATION NSClassFromString(@"NSApplication")
#define NSMENUITEM NSClassFromString(@"NSMenuItem")
#define NSWORKSPACE NSClassFromString(@"NSWorkspace")

#define NSApplicationDidBecomeActiveNotification @"NSApplicationDidBecomeActiveNotification"
#define NSApplicationDidBecomeActiveNotification @"NSApplicationDidBecomeActiveNotification"
#define NSApplicationDidFinishLaunchingNotification @"NSApplicationDidFinishLaunchingNotification"
#define NSApplicationDidHideNotification @"NSApplicationDidHideNotification"
#define NSApplicationDidResignActiveNotification @"NSApplicationDidResignActiveNotification"
#define NSApplicationDidResignActiveNotification @"NSApplicationDidResignActiveNotification"
#define NSApplicationDidUnhideNotification @"NSApplicationDidUnhideNotification"
#define NSApplicationWillBecomeActiveNotification @"NSApplicationWillBecomeActiveNotification"
#define NSApplicationWillTerminateNotification @"NSApplicationWillTerminateNotification"
#define NSApplicationWillTerminateNotification @"NSApplicationWillTerminateNotification"
#define NSControlTextDidBeginEditingNotification @"NSControlTextDidBeginEditingNotification"
#define NSControlTextDidEndEditingNotification @"NSControlTextDidEndEditingNotification"
#define NSMenuWillSendActionNotification @"NSMenuWillSendActionNotification"
#define NSTableViewSelectionDidChangeNotification @"NSTableViewSelectionDidChangeNotification"
#define NSUndoManagerDidRedoChangeNotification @"NSUndoManagerDidRedoChangeNotification"
#define NSUndoManagerDidUndoChangeNotification @"NSUndoManagerDidUndoChangeNotification"
#define NSWindowDidBecomeKeyNotification @"NSWindowDidBecomeKeyNotification"
#define NSWindowDidEnterFullScreenNotification @"NSWindowDidEnterFullScreenNotification"
#define NSWindowDidExitFullScreenNotification @"NSWindowDidExitFullScreenNotification"
#define NSWindowWillCloseNotification @"NSWindowWillCloseNotification"
#define NSWindowWillMiniaturizeNotification @"NSWindowWillMiniaturizeNotification"
#define NSWorkspaceScreensDidSleepNotification @"NSWorkspaceScreensDidSleepNotification"
#define NSWorkspaceScreensDidWakeNotification @"NSWorkspaceScreensDidWakeNotification"
1 change: 1 addition & 0 deletions Bugsnag/Helpers/BSGUIKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// When used in some memory constrained contexts such as a file provider extension, linking to UIKit is problematic.
// These macros exist to allow the use of UIKit without adding a link-time dependency on it.

// Calling code should be prepared for classes to not be found when UIKit is not linked.
#define UIAPPLICATION NSClassFromString(@"UIApplication")
#define UIDEVICE NSClassFromString(@"UIDevice")

Expand Down
2 changes: 1 addition & 1 deletion Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
#import "BSGUIKit.h"
#endif
#if TARGET_OS_OSX
#import <AppKit/AppKit.h>
#import "BSGAppKit.h"
#endif

// ============================================================================
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

## TBD

### Enhancements

* Bugsnag can now be used without AppKit, allowing use in daemons and other processes running in non-UI sessions.
[#1072](https://github.com/bugsnag/bugsnag-cocoa/pull/1072)

## 6.8.4 (2021-04-14)

### Enhancements
Expand Down
46 changes: 46 additions & 0 deletions Tests/BSGAppKitTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// BSGAppKitTests.m
// Bugsnag-macOSTests
//
// Created by Nick Dowell on 13/04/2021.
// Copyright © 2021 Bugsnag Inc. All rights reserved.
//

#import <XCTest/XCTest.h>

@interface BSGAppKitTests : XCTestCase

@end

@implementation BSGAppKitTests

- (void)testNotificationNames {
// The notifier uses hard-coded notification names so that it can avoid linking to AppKit.
// These tests ensure that the hard-coded names in BSGAppKit.h match the SDK.
#define ASSERT_NOTIFICATION_NAME(name) XCTAssertEqualObjects(name, @#name)
ASSERT_NOTIFICATION_NAME(NSApplicationDidBecomeActiveNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationDidBecomeActiveNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationDidFinishLaunchingNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationDidHideNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationDidResignActiveNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationDidResignActiveNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationDidUnhideNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationWillBecomeActiveNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationWillTerminateNotification);
ASSERT_NOTIFICATION_NAME(NSApplicationWillTerminateNotification);
ASSERT_NOTIFICATION_NAME(NSControlTextDidBeginEditingNotification);
ASSERT_NOTIFICATION_NAME(NSControlTextDidEndEditingNotification);
ASSERT_NOTIFICATION_NAME(NSMenuWillSendActionNotification);
ASSERT_NOTIFICATION_NAME(NSTableViewSelectionDidChangeNotification);
ASSERT_NOTIFICATION_NAME(NSUndoManagerDidRedoChangeNotification);
ASSERT_NOTIFICATION_NAME(NSUndoManagerDidUndoChangeNotification);
ASSERT_NOTIFICATION_NAME(NSWindowDidBecomeKeyNotification);
ASSERT_NOTIFICATION_NAME(NSWindowDidEnterFullScreenNotification);
ASSERT_NOTIFICATION_NAME(NSWindowDidExitFullScreenNotification);
ASSERT_NOTIFICATION_NAME(NSWindowWillCloseNotification);
ASSERT_NOTIFICATION_NAME(NSWindowWillMiniaturizeNotification);
ASSERT_NOTIFICATION_NAME(NSWorkspaceScreensDidSleepNotification);
ASSERT_NOTIFICATION_NAME(NSWorkspaceScreensDidWakeNotification);
}

@end

0 comments on commit d810ca8

Please sign in to comment.