Skip to content

Commit

Permalink
Harmonize code to get the class name, using Swift's built-in demangler
Browse files Browse the repository at this point in the history
  • Loading branch information
kstenerud committed Nov 22, 2024
1 parent 9b98eb3 commit 4b4d56c
Show file tree
Hide file tree
Showing 16 changed files with 248 additions and 26 deletions.
16 changes: 14 additions & 2 deletions BugsnagPerformance.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
09D807F52B9756B000D01DF5 /* BugsnagPerformanceSwiftUI.docc in Sources */ = {isa = PBXBuildFile; fileRef = 09D807F42B9756B000D01DF5 /* BugsnagPerformanceSwiftUI.docc */; };
09D807F62B9756B000D01DF5 /* BugsnagPerformanceSwiftUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 09D807F32B9756B000D01DF5 /* BugsnagPerformanceSwiftUI.h */; settings = {ATTRIBUTES = (Public, ); }; };
09E313042BF363020081F219 /* CrossTalkTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E313032BF363020081F219 /* CrossTalkTests.m */; };
09F23A8C2CE351ED00F0D769 /* BugsnagSwiftTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 09F23A8A2CE351ED00F0D769 /* BugsnagSwiftTools.h */; };
09F23A8D2CE351ED00F0D769 /* BugsnagSwiftTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 09F23A8B2CE351ED00F0D769 /* BugsnagSwiftTools.m */; };
09F23A8F2CE3521D00F0D769 /* BugsnagSwiftToolsImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F23A8E2CE3521D00F0D769 /* BugsnagSwiftToolsImpl.swift */; };
09FFD4402BEE3DE2009B0E04 /* BugsnagPerformanceCrossTalkAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 09FFD43E2BEE3DE2009B0E04 /* BugsnagPerformanceCrossTalkAPI.h */; };
09FFD4412BEE3DE2009B0E04 /* BugsnagPerformanceCrossTalkAPI.mm in Sources */ = {isa = PBXBuildFile; fileRef = 09FFD43F2BEE3DE2009B0E04 /* BugsnagPerformanceCrossTalkAPI.mm */; };
8A80DA8B2966CE940035BDA9 /* BugsnagPerformance.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72E4BB63359EA30E80116E2A /* BugsnagPerformance.framework */; };
Expand Down Expand Up @@ -308,6 +311,9 @@
09D807F42B9756B000D01DF5 /* BugsnagPerformanceSwiftUI.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = BugsnagPerformanceSwiftUI.docc; sourceTree = "<group>"; };
09DC62282C6A2EF6000AA8E1 /* BugsnagPerformanceSpanContext+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagPerformanceSpanContext+Private.h"; sourceTree = "<group>"; };
09E313032BF363020081F219 /* CrossTalkTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CrossTalkTests.m; sourceTree = "<group>"; };
09F23A8A2CE351ED00F0D769 /* BugsnagSwiftTools.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagSwiftTools.h; sourceTree = "<group>"; };
09F23A8B2CE351ED00F0D769 /* BugsnagSwiftTools.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BugsnagSwiftTools.m; sourceTree = "<group>"; };
09F23A8E2CE3521D00F0D769 /* BugsnagSwiftToolsImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugsnagSwiftToolsImpl.swift; sourceTree = "<group>"; };
09FFD43E2BEE3DE2009B0E04 /* BugsnagPerformanceCrossTalkAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagPerformanceCrossTalkAPI.h; sourceTree = "<group>"; };
09FFD43F2BEE3DE2009B0E04 /* BugsnagPerformanceCrossTalkAPI.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = BugsnagPerformanceCrossTalkAPI.mm; sourceTree = "<group>"; };
72E4BB63359EA30E80116E2A /* BugsnagPerformance.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BugsnagPerformance.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -537,7 +543,6 @@
0122C21F29019770002D243C /* Private */ = {
isa = PBXGroup;
children = (
966634D82C8A3939004A934D /* FrameRateMetrics */,
CB572EA829BB783200FD7A2A /* AppStateTracker.h */,
CB572EA929BB783200FD7A2A /* AppStateTracker.m */,
CBE8EA1C294B5E1500702950 /* Batch.h */,
Expand All @@ -552,10 +557,13 @@
09DC62282C6A2EF6000AA8E1 /* BugsnagPerformanceSpanContext+Private.h */,
CBE0873029FA984C007455F2 /* BugsnagPerformanceViewType.mm */,
CBE0873129FA984C007455F2 /* BugsnagPerformanceViewType+Private.h */,
09F23A8A2CE351ED00F0D769 /* BugsnagSwiftTools.h */,
09F23A8B2CE351ED00F0D769 /* BugsnagSwiftTools.m */,
CBA22C942A0137230066A2C1 /* EarlyConfiguration.h */,
CBA22C952A0137230066A2C1 /* EarlyConfiguration.mm */,
CBEC51D42976BCAD009C0CE3 /* Filesystem.h */,
CBEC51D52976BCAD009C0CE3 /* Filesystem.mm */,
966634D82C8A3939004A934D /* FrameRateMetrics */,
CBF7C5DF297A8E9100D47719 /* Gzip.h */,
CBF7C5E0297A8E9100D47719 /* Gzip.m */,
0122C22229019770002D243C /* IdGenerator.h */,
Expand Down Expand Up @@ -700,6 +708,7 @@
children = (
960EECED2B237561009FAA11 /* BugsnagPerformanceTrackedViewController.swift */,
096CBC152B1752F100534F0C /* BugsnagPerformanceSwiftUIInstrumentation.swift */,
09F23A8E2CE3521D00F0D769 /* BugsnagSwiftToolsImpl.swift */,
);
path = BugsnagPerformanceSwift;
sourceTree = "<group>";
Expand Down Expand Up @@ -841,6 +850,7 @@
0987F2792C32D4AD00777FD8 /* BugsnagPerformanceSpanContext.h in Headers */,
CBEC51C0296DB312009C0CE3 /* JSON.h in Headers */,
09B473072B23087D0024CF11 /* WeakSpansList.h in Headers */,
09F23A8C2CE351ED00F0D769 /* BugsnagSwiftTools.h in Headers */,
0921F02B2A67CBD600C764EB /* BugsnagPerformanceNetworkRequestInfo.h in Headers */,
0122C24A29019770002D243C /* AppStartupInstrumentation.h in Headers */,
CB04969B2915194E0097E526 /* OtlpUploader.h in Headers */,
Expand Down Expand Up @@ -1058,7 +1068,7 @@
ProvisioningStyle = Automatic;
};
B4A4A4DE1EA43C6C4D6D3894 = {
LastSwiftMigration = 1520;
LastSwiftMigration = 1540;
};
};
};
Expand Down Expand Up @@ -1177,6 +1187,7 @@
buildActionMask = 2147483647;
files = (
094FA7362B10EDE600112ED4 /* BugsnagPerformanceSwift.docc in Sources */,
09F23A8F2CE3521D00F0D769 /* BugsnagSwiftToolsImpl.swift in Sources */,
960EECF12B23DF9B009FAA11 /* BugsnagPerformanceTrackedViewController.swift in Sources */,
096CBC172B1752F700534F0C /* BugsnagPerformanceSwiftUIInstrumentation.swift in Sources */,
);
Expand Down Expand Up @@ -1219,6 +1230,7 @@
966634DC2C8A39C1004A934D /* FrozenFrameData.mm in Sources */,
0122C23E29019770002D243C /* BugsnagPerformanceSpan.mm in Sources */,
0987F27A2C32D4AD00777FD8 /* BugsnagPerformanceSpanContext.mm in Sources */,
09F23A8D2CE351ED00F0D769 /* BugsnagSwiftTools.m in Sources */,
968AA5FD2CCA5AB000BA69CF /* BSGPerformanceSharedSessionProxy.mm in Sources */,
CBEC51DD2976F1F9009C0CE3 /* RetryQueue.mm in Sources */,
01A414CE2913C0F0003152A4 /* SpanAttributes.mm in Sources */,
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

### Bug fixes

* Improved Swift mangled name handling when reporting view spans.
[344](https://github.com/bugsnag/bugsnag-cocoa-performance/pull/344)

## 1.10.2 (2024-10-31)

* Fixed a crash after shared NSURLSession invalidate
Expand Down
24 changes: 16 additions & 8 deletions Example/Example/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="yGw-kV-UMF">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="yGw-kV-UMF">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
Expand All @@ -18,7 +18,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="I5S-OR-fvf">
<rect key="frame" x="86.5" y="304.5" width="241.5" height="287"/>
<rect key="frame" x="86.5" y="279.5" width="241.5" height="337.5"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0ga-0O-hoa">
<rect key="frame" x="15" y="0.0" width="211.5" height="34.5"/>
Expand All @@ -28,40 +28,48 @@
<segue destination="K5u-LY-aNB" kind="show" id="C85-Df-PBE"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="XlC-xf-cfi">
<rect key="frame" x="16" y="50.5" width="209.5" height="34.5"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="GenericViewController &gt;"/>
<connections>
<action selector="showGenericView:" destination="BYZ-38-t0r" eventType="touchUpInside" id="8AE-aE-SLG"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jUe-GT-sTK">
<rect key="frame" x="17.5" y="50.5" width="206" height="34.5"/>
<rect key="frame" x="17.5" y="101" width="206" height="34.5"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="SwiftUI View (manual) &gt;"/>
<connections>
<action selector="showSwiftUIView:" destination="BYZ-38-t0r" eventType="touchUpInside" id="7Ab-Jo-wPm"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WB9-jo-IaN">
<rect key="frame" x="0.0" y="101" width="241.5" height="34.5"/>
<rect key="frame" x="0.0" y="151.5" width="241.5" height="34.5"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="UIViewController (ignored) &gt;"/>
<connections>
<segue destination="l9J-Wk-fsy" kind="show" id="aaN-Q5-KdO"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0dA-WH-9hh">
<rect key="frame" x="16" y="151.5" width="209" height="34.5"/>
<rect key="frame" x="16" y="202" width="209" height="34.5"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="IgnoredViewController &gt;"/>
<connections>
<segue destination="V48-0c-1l8" kind="show" id="gAB-0C-fPE"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WLB-9O-ylx">
<rect key="frame" x="43" y="202" width="155" height="34.5"/>
<rect key="frame" x="43" y="252.5" width="155" height="34.5"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Network Request"/>
<connections>
<action selector="DoNetworkRequest:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Llg-LD-ytB"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="esF-0Z-lnd" userLabel="Manual Span">
<rect key="frame" x="59.5" y="252.5" width="122.5" height="34.5"/>
<rect key="frame" x="59.5" y="303" width="122.5" height="34.5"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Manual Span"/>
<connections>
Expand Down
4 changes: 2 additions & 2 deletions Example/Example/SomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import BugsnagPerformanceSwift
import SwiftUI

@available(iOS 13.0.0, *)
struct SomeView: View {
struct SomeView<T>: View {
@State var data: Data?
@State var deferringViewLoadSpan = true

Expand Down Expand Up @@ -61,6 +61,6 @@ struct SomeView: View {
@available(iOS 13.0.0, *)
struct SomeView_Previews: PreviewProvider {
static var previews: some View {
SomeView()
SomeView<Int>()
}
}
7 changes: 6 additions & 1 deletion Example/Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ import BugsnagPerformance

class ViewController: UIViewController {

@IBAction func showGenericView(_ sender: Any) {
let vc = GenericViewController<Int>()
show(vc, sender:sender)
}

@IBAction func showSwiftUIView(_ sender: Any) {
if #available(iOS 13.0.0, *) {
show(UIHostingController(rootView: SomeView()), sender: sender)
show(UIHostingController(rootView: SomeView<Int>().bugsnagTraced()), sender: sender)
} else {
present(UIAlertController(
title: "Error",
Expand Down
30 changes: 30 additions & 0 deletions Example/ExampleLibrary/AnotherViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import UIKit
import BugsnagPerformance

class AnotherViewController: UIViewController {

Expand Down Expand Up @@ -37,3 +38,32 @@ class AnotherViewController: UIViewController {
*/

}

class GenericViewController<T>: UIViewController {
var value: T?

init() {
super.init(nibName: nil, bundle: nil)
value = nil
}

required init?(coder: NSCoder) {
super.init(coder: coder)
value = nil
}

override func loadView() {
print("GenericViewController", #function)
super.loadView()
}

override func viewDidLoad() {
print("GenericViewController", #function)
super.viewDidLoad()
}

override func viewDidAppear(_ animated: Bool) {
print("GenericViewController", #function)
super.viewDidAppear(animated)
}
}
23 changes: 23 additions & 0 deletions Sources/BugsnagPerformance/Private/BugsnagSwiftTools.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// BugsnagSwiftTools.h
// BugsnagPerformance-iOS
//
// Created by Karl Stenerud on 12.11.24.
// Copyright © 2024 Bugsnag. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface BugsnagSwiftTools : NSObject

/**
* Get the demangled description of an object's class.
* Note: object must not be a class, otherwise demangling won't work!
*/
+ (NSString * _Nonnull)demangledClassNameFromInstance:(id _Nonnull)object;

@end

NS_ASSUME_NONNULL_END
41 changes: 41 additions & 0 deletions Sources/BugsnagPerformance/Private/BugsnagSwiftTools.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// BugsnagSwiftTools.m
// BugsnagPerformance-iOS
//
// Created by Karl Stenerud on 12.11.24.
// Copyright © 2024 Bugsnag. All rights reserved.
//

#import "BugsnagSwiftTools.h"
#import <BugsnagPerformance/BugsnagPerformanceTrackedViewContainer.h>

@implementation BugsnagSwiftTools

// Selector used by BugsnagSwiftToolsImpl
+ (NSString * _Nonnull)demangledClassNameFromInstanceWithObject:(id _Nonnull)object {
return [self demangledClassNameFromInstance:object];
}

+ (NSString * _Nonnull)demangledClassNameFromInstance:(id _Nonnull)object {
// BugsnagSwiftToolsImpl is part of the optional BugsnagPerformanceSwift, and may not be linked in
static Class impl = nil;
static bool implExists = false;
static dispatch_once_t once;
dispatch_once(&once, ^{
impl = NSClassFromString(@"BugsnagPerformanceSwift.BugsnagSwiftToolsImpl");
implExists = [impl respondsToSelector:@selector(demangledClassNameFromInstanceWithObject:)];
});
if (implExists) {
return [impl demangledClassNameFromInstanceWithObject:object];
}

// Fallback if BugsnagSwiftToolsImpl is not available

if ([object respondsToSelector:@selector(bugsnagPerformanceTrackedViewName)]) {
return [(id)object bugsnagPerformanceTrackedViewName];
}

return NSStringFromClass([object class]);
}

@end
Loading

0 comments on commit 4b4d56c

Please sign in to comment.