From 91450ced7c48c26c50805f781eda3292a6085526 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 30 Oct 2022 17:10:58 -0400 Subject: [PATCH] Use Sentry for crash reporting --- .gitignore | 1 + Tusker.xcodeproj/project.pbxproj | 241 +++++++++++++++--- .../xcshareddata/xcschemes/Tusker.xcscheme | 2 +- Tusker/AppDelegate.swift | 53 ++-- Tusker/Info.plist | 2 + Tusker/MainSceneDelegate.swift | 19 -- .../CrashReporterViewController.swift | 64 ----- .../IssueReporterViewController.swift | 1 - Tusker/TimelineLikeController.swift | 4 +- Tusker/Views/Attachments/AttachmentView.swift | 4 +- 10 files changed, 233 insertions(+), 158 deletions(-) delete mode 100644 Tusker/Screens/Crash Reporter/CrashReporterViewController.swift diff --git a/.gitignore b/.gitignore index fc6431b8b1..e64ccb5fbf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +Dist.xcconfig .DS_Store MyPlayground.playground/ diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 368b0a1f7d..1d9f369974 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -25,7 +25,6 @@ D60E2F292442372B005F8713 /* AccountMO.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60E2F252442372B005F8713 /* AccountMO.swift */; }; D60E2F2C24423EAD005F8713 /* LazilyDecoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60E2F2B24423EAD005F8713 /* LazilyDecoding.swift */; }; D60E2F2E244248BF005F8713 /* MastodonCachePersistentStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60E2F2D244248BF005F8713 /* MastodonCachePersistentStore.swift */; }; - D6114E0927F3EA3D0080E273 /* CrashReporterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6114E0827F3EA3D0080E273 /* CrashReporterViewController.swift */; }; D6114E0D27F7FEB30080E273 /* TrendingStatusesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6114E0C27F7FEB30080E273 /* TrendingStatusesViewController.swift */; }; D6114E1127F899B30080E273 /* TrendingLinksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6114E1027F899B30080E273 /* TrendingLinksViewController.swift */; }; D6114E1327F89B440080E273 /* TrendingLinkTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6114E1227F89B440080E273 /* TrendingLinkTableViewCell.swift */; }; @@ -95,6 +94,7 @@ D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */; }; D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */; }; D6370B9C24421FF30092A7FF /* Tusker.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = D6370B9A24421FF30092A7FF /* Tusker.xcdatamodeld */; }; + D63CC702290EC0B8000E19DE /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = D63CC701290EC0B8000E19DE /* Sentry */; }; D63D8DF42850FE7A008D95E1 /* ViewTags.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63D8DF32850FE7A008D95E1 /* ViewTags.swift */; }; D63F9C6E241D2D85004C03CF /* CompositionAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63F9C6D241D2D85004C03CF /* CompositionAttachment.swift */; }; D6403CC224A6B72D00E81C55 /* VisualEffectImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6403CC124A6B72D00E81C55 /* VisualEffectImageButton.swift */; }; @@ -195,7 +195,6 @@ D69693FA25859A8000F4E116 /* ComposeSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69693F925859A8000F4E116 /* ComposeSceneDelegate.swift */; }; D6969E9E240C81B9002843CE /* NSTextAttachment+Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6969E9D240C81B9002843CE /* NSTextAttachment+Emoji.swift */; }; D6969EA0240C8384002843CE /* EmojiLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6969E9F240C8384002843CE /* EmojiLabel.swift */; }; - D69CCBBF249E6EFD000AF167 /* CrashReporter in Frameworks */ = {isa = PBXBuildFile; productRef = D69CCBBE249E6EFD000AF167 /* CrashReporter */; }; D6A00B1D26379FC900316AD4 /* PollOptionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A00B1C26379FC900316AD4 /* PollOptionsView.swift */; }; D6A3BC7C232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3BC7A232195C600FD64D5 /* ActionNotificationGroupTableViewCell.swift */; }; D6A3BC7D232195C600FD64D5 /* ActionNotificationGroupTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6A3BC7B232195C600FD64D5 /* ActionNotificationGroupTableViewCell.xib */; }; @@ -379,7 +378,6 @@ D60E2F252442372B005F8713 /* AccountMO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountMO.swift; sourceTree = ""; }; D60E2F2B24423EAD005F8713 /* LazilyDecoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazilyDecoding.swift; sourceTree = ""; }; D60E2F2D244248BF005F8713 /* MastodonCachePersistentStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonCachePersistentStore.swift; sourceTree = ""; }; - D6114E0827F3EA3D0080E273 /* CrashReporterViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReporterViewController.swift; sourceTree = ""; }; D6114E0C27F7FEB30080E273 /* TrendingStatusesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingStatusesViewController.swift; sourceTree = ""; }; D6114E1027F899B30080E273 /* TrendingLinksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingLinksViewController.swift; sourceTree = ""; }; D6114E1227F89B440080E273 /* TrendingLinkTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingLinkTableViewCell.swift; sourceTree = ""; }; @@ -448,6 +446,7 @@ D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+TimeAgo.swift"; sourceTree = ""; }; D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesNavigationController.swift; sourceTree = ""; }; D6370B9B24421FF30092A7FF /* Tusker.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Tusker.xcdatamodel; sourceTree = ""; }; + D63CC703290EC472000E19DE /* Dist.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Dist.xcconfig; sourceTree = ""; }; D63D8DF32850FE7A008D95E1 /* ViewTags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewTags.swift; sourceTree = ""; }; D63F9C6D241D2D85004C03CF /* CompositionAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionAttachment.swift; sourceTree = ""; }; D6403CC124A6B72D00E81C55 /* VisualEffectImageButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisualEffectImageButton.swift; sourceTree = ""; }; @@ -682,10 +681,10 @@ buildActionMask = 2147483647; files = ( D674A50927F9128D00BA03AC /* Pachyderm in Frameworks */, - D69CCBBF249E6EFD000AF167 /* CrashReporter in Frameworks */, D60CFFDB24A290BA00D00083 /* SwiftSoup in Frameworks */, D6552367289870790048A653 /* ScreenCorners in Frameworks */, D6676CA527A8D0020052936B /* WebURLFoundationExtras in Frameworks */, + D63CC702290EC0B8000E19DE /* Sentry in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1343,6 +1342,7 @@ D6D4DDC3212518A000E1C4BB = { isa = PBXGroup; children = ( + D63CC703290EC472000E19DE /* Dist.xcconfig */, D674A50727F910F300BA03AC /* Pachyderm */, D6D4DDCE212518A000E1C4BB /* Tusker */, D6D4DDE3212518A200E1C4BB /* TuskerTests */, @@ -1469,7 +1469,6 @@ D6F2E960249E772F005846BB /* Crash Reporter */ = { isa = PBXGroup; children = ( - D6114E0827F3EA3D0080E273 /* CrashReporterViewController.swift */, D6F2E963249E8BFD005846BB /* IssueReporterViewController.swift */, D6F2E964249E8BFD005846BB /* IssueReporterViewController.xib */, ); @@ -1501,7 +1500,7 @@ D6F953E52125197500CF0F2B /* Embed Frameworks */, D65F612C23AE957600F3CFD3 /* Embed debug-only frameworks */, D6E3438F2659849800C4AA01 /* Embed Foundation Extensions */, - D6F1F9E127B0677000CB7D88 /* ShellScript */, + D63CC704290EC913000E19DE /* ShellScript */, ); buildRules = ( ); @@ -1510,11 +1509,11 @@ ); name = Tusker; packageProductDependencies = ( - D69CCBBE249E6EFD000AF167 /* CrashReporter */, D60CFFDA24A290BA00D00083 /* SwiftSoup */, D6676CA427A8D0020052936B /* WebURLFoundationExtras */, D674A50827F9128D00BA03AC /* Pachyderm */, D6552366289870790048A653 /* ScreenCorners */, + D63CC701290EC0B8000E19DE /* Sentry */, ); productName = Tusker; productReference = D6D4DDCC212518A000E1C4BB /* Tusker.app */; @@ -1621,10 +1620,10 @@ ); mainGroup = D6D4DDC3212518A000E1C4BB; packageReferences = ( - D69CCBBD249E6EFD000AF167 /* XCRemoteSwiftPackageReference "plcrashreporter" */, D60CFFD924A290BA00D00083 /* XCRemoteSwiftPackageReference "SwiftSoup" */, D6676CA127A8D0020052936B /* XCRemoteSwiftPackageReference "swift-url" */, D6552365289870790048A653 /* XCRemoteSwiftPackageReference "ScreenCorners" */, + D63CC700290EC0B8000E19DE /* XCRemoteSwiftPackageReference "sentry-cocoa" */, ); productRefGroup = D6D4DDCD212518A000E1C4BB /* Products */; projectDirPath = ""; @@ -1701,6 +1700,26 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + D63CC704290EC913000E19DE /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}", + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/bash; + shellScript = "echo \"$CONFIGURATION\"\nif [ \"$CONFIGURATION\" == \"Dist\" ]; then\nif which sentry-cli >/dev/null; then\nexport SENTRY_ORG=vaccor\nexport SENTRY_PROJECT=tusker\nERROR=$(sentry-cli upload-dif \"$DWARF_DSYM_FOLDER_PATH\" --force-foreground 2>&1 >/dev/null)\nif [ ! $? -eq 0 ]; then\necho \"sentry-cli uploaded debug info\"\nelse\necho \"error: sentry-cli - $ERROR\"\nfi\nelse\necho \"error: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi\nfi\n"; + showEnvVarsInLog = 0; + }; D65F612C23AE957600F3CFD3 /* Embed debug-only frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1723,24 +1742,6 @@ shellPath = /bin/sh; shellScript = "#if [ \"${CONFIGURATION}\" == \"Debug\" ]; then\n# echo \"Embedding ${SCRIPT_INPUT_FILE_0}\"\n# cp -R $SCRIPT_INPUT_FILE_0 $SCRIPT_OUTPUT_FILE_0\n# codesign --force --verbose --sign $EXPANDED_CODE_SIGN_IDENTITY $SCRIPT_OUTPUT_FILE_0\n# \n# echo \"Embedding ${SCRIPT_INPUT_FILE_1}\"\n# cp -R $SCRIPT_INPUT_FILE_1 $SCRIPT_OUTPUT_FILE_1\n# codesign --force --verbose --sign $EXPANDED_CODE_SIGN_IDENTITY $SCRIPT_OUTPUT_FILE_1\n#else\n# echo \"Skipping embedding debug frameworks\"\n#fi\n"; }; - D6F1F9E127B0677000CB7D88 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\n# the nested framework doens't get signed automatically for some reason\n# so we sign it ourselves\n#codesign --force --verbose --sign $EXPANDED_CODE_SIGN_IDENTITY \"$BUILT_PRODUCTS_DIR/Tusker.app/Frameworks/Pachyderm.framework/Frameworks/WebURL.framework\"\n\n# xcode wants to include the weburl framework twice for some reason, but the app store doesn't like nested frameworks\n# we already have a copy in the app's Frameworks/ dir, so we can delete the nested one\nif [ \"$(ls \"$BUILT_PRODUCTS_DIR/Tusker.app/Frameworks/Pachyderm.framework/Frameworks/\")\" -ne \"WebURL.framework\" ]; then\n exit 1\nfi\nrm -rf \"$BUILT_PRODUCTS_DIR/Tusker.app/Frameworks/Pachyderm.framework/Frameworks/\"\n"; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1991,7 +1992,6 @@ D677284E24ECC01D00C732D3 /* Draft.swift in Sources */, D667E5F12134D5050057A976 /* UIViewController+Delegates.swift in Sources */, D6BC8748219738E1006163F1 /* EnhancedTableViewController.swift in Sources */, - D6114E0927F3EA3D0080E273 /* CrashReporterViewController.swift in Sources */, D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */, D6E426B325337C7000C02E1C /* CustomEmojiImageView.swift in Sources */, D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */, @@ -2087,8 +2087,164 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + D63CC705290ECE77000E19DE /* Dist */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D63CC703290EC472000E19DE /* Dist.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZE_OBJECT_LIFETIME = YES; + VALIDATE_PRODUCT = YES; + }; + name = Dist; + }; + D63CC706290ECE77000E19DE /* Dist */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 41; + DEVELOPMENT_TEAM = V4WK9KR9U2; + INFOPLIST_FILE = Tusker/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 2022.1; + OTHER_CODE_SIGN_FLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTS_MACCATALYST = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,6"; + }; + name = Dist; + }; + D63CC707290ECE77000E19DE /* Dist */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = V4WK9KR9U2; + INFOPLIST_FILE = TuskerTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker.TuskerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Tusker.app/Tusker"; + }; + name = Dist; + }; + D63CC708290ECE77000E19DE /* Dist */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = V4WK9KR9U2; + INFOPLIST_FILE = TuskerUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker.TuskerUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Tusker; + }; + name = Dist; + }; + D63CC709290ECE77000E19DE /* Dist */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 41; + DEVELOPMENT_TEAM = V4WK9KR9U2; + INFOPLIST_FILE = OpenInTusker/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.1; + "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 2022.1; + PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Tusker.OpenInTusker; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,6"; + }; + name = Dist; + }; D6D4DDF2212518A200E1C4BB /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D63CC703290EC472000E19DE /* Dist.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -2411,6 +2567,7 @@ buildConfigurations = ( D6D4DDF2212518A200E1C4BB /* Debug */, D6D4DDF3212518A200E1C4BB /* Release */, + D63CC705290ECE77000E19DE /* Dist */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2420,6 +2577,7 @@ buildConfigurations = ( D6D4DDF5212518A200E1C4BB /* Debug */, D6D4DDF6212518A200E1C4BB /* Release */, + D63CC706290ECE77000E19DE /* Dist */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2429,6 +2587,7 @@ buildConfigurations = ( D6D4DDF8212518A200E1C4BB /* Debug */, D6D4DDF9212518A200E1C4BB /* Release */, + D63CC707290ECE77000E19DE /* Dist */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2438,6 +2597,7 @@ buildConfigurations = ( D6D4DDFB212518A200E1C4BB /* Debug */, D6D4DDFC212518A200E1C4BB /* Release */, + D63CC708290ECE77000E19DE /* Dist */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2447,6 +2607,7 @@ buildConfigurations = ( D6E343B7265AAD6B00C4AA01 /* Debug */, D6E343B8265AAD6B00C4AA01 /* Release */, + D63CC709290ECE77000E19DE /* Dist */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2462,6 +2623,14 @@ minimumVersion = 2.3.2; }; }; + D63CC700290EC0B8000E19DE /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/getsentry/sentry-cocoa.git"; + requirement = { + kind = upToNextMinorVersion; + minimumVersion = 7.29.0; + }; + }; D6552365289870790048A653 /* XCRemoteSwiftPackageReference "ScreenCorners" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kylebshr/ScreenCorners"; @@ -2478,14 +2647,6 @@ kind = branch; }; }; - D69CCBBD249E6EFD000AF167 /* XCRemoteSwiftPackageReference "plcrashreporter" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/microsoft/plcrashreporter"; - requirement = { - kind = upToNextMinorVersion; - minimumVersion = 1.11.0; - }; - }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -2498,6 +2659,11 @@ isa = XCSwiftPackageProductDependency; productName = Pachyderm; }; + D63CC701290EC0B8000E19DE /* Sentry */ = { + isa = XCSwiftPackageProductDependency; + package = D63CC700290EC0B8000E19DE /* XCRemoteSwiftPackageReference "sentry-cocoa" */; + productName = Sentry; + }; D6552366289870790048A653 /* ScreenCorners */ = { isa = XCSwiftPackageProductDependency; package = D6552365289870790048A653 /* XCRemoteSwiftPackageReference "ScreenCorners" */; @@ -2512,11 +2678,6 @@ isa = XCSwiftPackageProductDependency; productName = Pachyderm; }; - D69CCBBE249E6EFD000AF167 /* CrashReporter */ = { - isa = XCSwiftPackageProductDependency; - package = D69CCBBD249E6EFD000AF167 /* XCRemoteSwiftPackageReference "plcrashreporter" */; - productName = CrashReporter; - }; /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ diff --git a/Tusker.xcodeproj/xcshareddata/xcschemes/Tusker.xcscheme b/Tusker.xcodeproj/xcshareddata/xcschemes/Tusker.xcscheme index 2dbcf1ce7b..eea12641eb 100644 --- a/Tusker.xcodeproj/xcshareddata/xcschemes/Tusker.xcscheme +++ b/Tusker.xcodeproj/xcshareddata/xcschemes/Tusker.xcscheme @@ -127,7 +127,7 @@ buildConfiguration = "Debug"> diff --git a/Tusker/AppDelegate.swift b/Tusker/AppDelegate.swift index d9f211952c..c306483f16 100644 --- a/Tusker/AppDelegate.swift +++ b/Tusker/AppDelegate.swift @@ -7,22 +7,19 @@ // import UIKit -import CrashReporter import CoreData import OSLog +import Sentry let stateRestorationLogger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "StateRestoration") @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - static private(set) var crashReporter: PLCrashReporter! - static var pendingCrashReport: PLCrashReport? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - #if !DEBUG - setupCrashReporter() - #endif + + configureSentry() AppShortcutItem.createItems(for: application) @@ -52,22 +49,28 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } - private func setupCrashReporter() { - let config = PLCrashReporterConfig(signalHandlerType: .BSD, symbolicationStrategy: .all) - AppDelegate.crashReporter = PLCrashReporter(configuration: config) - let callbacksPtr = UnsafeMutablePointer.allocate(capacity: 1) - callbacksPtr.pointee = PLCrashReporterCallbacks(version: 0, context: nil, handleSignal: crashCallback) - // setCrashCallbacks, it's poorly imported into Swift - AppDelegate.crashReporter.setCrash(callbacksPtr) - - if AppDelegate.crashReporter.hasPendingCrashReport(), - let data = try? AppDelegate.crashReporter.loadPendingCrashReportDataAndReturnError(), - let report = try? PLCrashReport(data: data) { - AppDelegate.crashReporter.purgePendingCrashReport() - AppDelegate.pendingCrashReport = report + private func configureSentry() { + guard let dsn = Bundle.main.object(forInfoDictionaryKey: "SentryDSN") as? String, + !dsn.isEmpty else { + return + } + SentrySDK.start { options in + #if DEBUG + options.debug = true + options.environment = "dev" + #endif + + // the '//' in the full url can't be escaped, so we have to add the scheme back + options.dsn = "https://\(dsn)" + + options.enableSwizzling = false + options.enableAutoSessionTracking = false + options.enableOutOfMemoryTracking = false + options.enableAutoPerformanceTracking = false + options.enableNetworkTracking = false + options.enableAppHangTracking = false + options.enableCoreDataTracking = false } - - AppDelegate.crashReporter.enable() } override func buildMenu(with builder: UIMenuBuilder) { @@ -119,11 +122,3 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } -private func crashCallback(info: UnsafeMutablePointer!, uap: UnsafeMutablePointer!, context: UnsafeMutableRawPointer?) { - // read logs on the main queue in order to block further user interaction while we're crashing - // since getting the log data can take upwards of a second, even for very few entries - // synchronously dispatch because the callback can't return until we're ready to abort - DispatchQueue.main.sync { - Logging.writeDataForCrash() - } -} diff --git a/Tusker/Info.plist b/Tusker/Info.plist index 25c8e98dc2..a1b8dc719c 100644 --- a/Tusker/Info.plist +++ b/Tusker/Info.plist @@ -2,6 +2,8 @@ + SentryDSN + $(SENTRY_DSN) OSLogPreferences space.vaccor.Tusker diff --git a/Tusker/MainSceneDelegate.swift b/Tusker/MainSceneDelegate.swift index 8bd8953ce3..5584eb805d 100644 --- a/Tusker/MainSceneDelegate.swift +++ b/Tusker/MainSceneDelegate.swift @@ -8,7 +8,6 @@ import UIKit import Pachyderm -import CrashReporter import MessageUI import CoreData @@ -32,15 +31,10 @@ class MainSceneDelegate: UIResponder, UIWindowSceneDelegate { window = UIWindow(windowScene: windowScene) - if let report = AppDelegate.pendingCrashReport { - AppDelegate.pendingCrashReport = nil - handlePendingCrashReport(report, session: session) - } else { showAppOrOnboardingUI(session: session) if connectionOptions.urlContexts.count > 0 { self.scene(scene, openURLContexts: connectionOptions.urlContexts) } - } window!.makeKeyAndVisible() @@ -142,19 +136,6 @@ class MainSceneDelegate: UIResponder, UIWindowSceneDelegate { } } - private func handlePendingCrashReport(_ report: PLCrashReport, session: UISceneSession) { - #if !DEBUG - guard MFMailComposeViewController.canSendMail() else { - print("Cannot send email") - showAppOrOnboardingUI(session: session) - return - } - - window!.rootViewController = CrashReporterViewController.create(report: report, dismiss: { - self.showAppOrOnboardingUI() - }) - #endif - } func showAppOrOnboardingUI(session: UISceneSession? = nil) { let session = session ?? window!.windowScene!.session diff --git a/Tusker/Screens/Crash Reporter/CrashReporterViewController.swift b/Tusker/Screens/Crash Reporter/CrashReporterViewController.swift deleted file mode 100644 index 7a77ef2b14..0000000000 --- a/Tusker/Screens/Crash Reporter/CrashReporterViewController.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// CrashReporterViewController.swift -// Tusker -// -// Created by Shadowfacts on 3/29/22. -// Copyright © 2022 Shadowfacts. All rights reserved. -// - -import UIKit -import CrashReporter - -class CrashReporterViewController: IssueReporterViewController { - - private let report: PLCrashReport - private var logURL: URL? - - override var preamble: String { - "Tusker has detected that it crashed the last time it was running. You can email the report to the developer or skip sending and continue to the app. You may review the report below before sending.\n\nIf you choose to send the report, please include any additional details about what you were doing prior to the crash that may be pertinent." - } - - override var subject: String { - "Tusker Crash Report" - } - - static func create(report: PLCrashReport, dismiss: @escaping () -> Void) -> UINavigationController { - return create(CrashReporterViewController(report: report, dismiss: dismiss)) - } - - private init(report: PLCrashReport, dismiss: @escaping () -> Void) { - self.report = report - self.logURL = Logging.logURLForLastCrash() - let reportText = PLCrashReportTextFormatter.stringValue(for: report, with: PLCrashReportTextFormatiOS)! - let timestamp = ISO8601DateFormatter().string(from: report.systemInfo.timestamp) - let reportFilename = "Tusker-crash-\(timestamp).crash" - - super.init(reportText: reportText, reportFilename: reportFilename, dismiss: dismiss) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func viewDidLoad() { - super.viewDidLoad() - - navigationItem.title = NSLocalizedString("Crash Detected", comment: "crash reporter title") - } - - override func getLogData() async -> (Data, String)? { - guard let logURL, - let data = try? Data(contentsOf: logURL) else { - return nil - } - return (data, logURL.lastPathComponent) - } - - override func finishedReport() { - super.finishedReport() - if let logURL { - try? FileManager.default.removeItem(at: logURL) - } - } - -} diff --git a/Tusker/Screens/Crash Reporter/IssueReporterViewController.swift b/Tusker/Screens/Crash Reporter/IssueReporterViewController.swift index 2330f51dab..64dff09100 100644 --- a/Tusker/Screens/Crash Reporter/IssueReporterViewController.swift +++ b/Tusker/Screens/Crash Reporter/IssueReporterViewController.swift @@ -7,7 +7,6 @@ // import UIKit -import CrashReporter import MessageUI import OSLog diff --git a/Tusker/TimelineLikeController.swift b/Tusker/TimelineLikeController.swift index 9eae833342..523bc58dbe 100644 --- a/Tusker/TimelineLikeController.swift +++ b/Tusker/TimelineLikeController.swift @@ -40,7 +40,7 @@ actor TimelineLikeController { willSet { guard state.canTransition(to: newValue) else { logger.error("State \(self.state.debugDescription, privacy: .public) cannot transition to \(newValue.debugDescription, privacy: .public)") - preconditionFailure("cannot transition to state") + fatalError("State \(state) cannot transition to \(newValue)") } logger.debug("State: \(self.state.debugDescription, privacy: .public) -> \(newValue.debugDescription, privacy: .public)") } @@ -123,7 +123,7 @@ actor TimelineLikeController { private func emit(event: Event) async { guard state.canEmit(event: event) else { logger.error("State \(self.state.debugDescription, privacy: .public) cannot emit event: \(event.debugDescription, privacy: .public)") - preconditionFailure("state cannot emit event") + fatalError("State \(state) cannot emit event: \(event)") } switch event { case .addLoadingIndicator: diff --git a/Tusker/Views/Attachments/AttachmentView.swift b/Tusker/Views/Attachments/AttachmentView.swift index f256ad8c51..3fd8f93adb 100644 --- a/Tusker/Views/Attachments/AttachmentView.swift +++ b/Tusker/Views/Attachments/AttachmentView.swift @@ -104,7 +104,7 @@ class AttachmentView: GIFImageView { func loadAttachment() { guard AttachmentsContainerView.supportedAttachmentTypes.contains(attachment.kind) else { - preconditionFailure("invalid attachment type") + fatalError("invalid attachment type") } if let hash = attachment.blurHash { @@ -137,7 +137,7 @@ class AttachmentView: GIFImageView { case .gifv: loadGifv() default: - preconditionFailure("invalid attachment type") + fatalError("invalid attachment type") } }