Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PLAT-6281] Remove reliance on AppKit to allow use in daemons #1072

Merged
merged 2 commits into from
Apr 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
3 changes: 2 additions & 1 deletion Bugsnag/Storage/BSGFileLocations.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ static BOOL ensureDirExists(NSString *path) {

rootPath = [NSString stringWithFormat:@"%@/com.bugsnag.Bugsnag/%@/%@",
url.path,
[NSBundle mainBundle].bundleIdentifier,
// Processes that don't have an Info.plist have no bundleIdentifier
NSBundle.mainBundle.bundleIdentifier ?: NSProcessInfo.processInfo.processName,
fsVersion];

// If we can't even create the root dir, all is lost, and no file ops can be allowed.
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
2 changes: 1 addition & 1 deletion Tests/BSGStorageMigratorTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ - (NSString *)getV1RootDir {

return [NSString stringWithFormat:@"%@/com.bugsnag.Bugsnag/%@/v1",
dirs[0],
[NSBundle mainBundle].bundleIdentifier];
NSBundle.mainBundle.bundleIdentifier ?: NSProcessInfo.processInfo.processName];
}

- (NSDictionary *)getDirs {
Expand Down