From 29477b5c12163dbde110f5b3cf156cb71f889130 Mon Sep 17 00:00:00 2001 From: CORE-FOLDCCCore <1813547935@qq.com> Date: Fri, 12 Jun 2026 16:42:45 +0800 Subject: [PATCH] Support iOS crash reporting --- CHANGELOG.md | 12 ++ Editor/CrashPostProcessBuildIOS.cs | 65 ++++++++ Editor/CrashPostProcessBuildIOS.cs.meta | 3 + Plugins/iOS.meta | 8 + Plugins/iOS/FoldCCBuglyBridge.mm | 190 ++++++++++++++++++++++++ Plugins/iOS/FoldCCBuglyBridge.mm.meta | 34 +++++ package.json | 4 +- 7 files changed, 314 insertions(+), 2 deletions(-) create mode 100644 Editor/CrashPostProcessBuildIOS.cs create mode 100644 Editor/CrashPostProcessBuildIOS.cs.meta create mode 100644 Plugins/iOS.meta create mode 100644 Plugins/iOS/FoldCCBuglyBridge.mm create mode 100644 Plugins/iOS/FoldCCBuglyBridge.mm.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b2d24..ff12002 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,3 +7,15 @@ ### 修复 * 优化package.json文件 + +# [1.0.2] + +### 新增 + +* 支持 iOS 平台 Bugly SDK 桥接。 +* iOS 导出 Xcode 工程时自动写入 `pod 'Bugly', '~> 2.6'` 依赖。 + +### 调整 + +* Unity 工程版本升级到 2022.3.62f3c1。 +* package.json 的 Unity 兼容版本调整为 2022.3。 diff --git a/Editor/CrashPostProcessBuildIOS.cs b/Editor/CrashPostProcessBuildIOS.cs new file mode 100644 index 0000000..0f42421 --- /dev/null +++ b/Editor/CrashPostProcessBuildIOS.cs @@ -0,0 +1,65 @@ +#if UNITY_IOS + +using System; +using System.IO; +using UnityEditor; +using UnityEditor.Callbacks; +using UnityEngine; + +namespace Editor +{ + public static class CrashPostProcessBuildIOS + { + private const string PodLine = " pod 'Bugly', '~> 2.6'"; + private const string UnityFrameworkTarget = "target 'UnityFramework' do"; + + [PostProcessBuild(980)] + public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject) + { + if (target != BuildTarget.iOS) + { + return; + } + + EnsureBuglyPod(pathToBuiltProject); + } + + private static void EnsureBuglyPod(string pathToBuiltProject) + { + string podfilePath = Path.Combine(pathToBuiltProject, "Podfile"); + string content = File.Exists(podfilePath) ? File.ReadAllText(podfilePath) : string.Empty; + + if (content.Contains("pod 'Bugly'") || content.Contains("pod \"Bugly\"")) + { + return; + } + + if (string.IsNullOrWhiteSpace(content)) + { + File.WriteAllText(podfilePath, + "platform :ios, '9.0'" + Environment.NewLine + + Environment.NewLine + + UnityFrameworkTarget + Environment.NewLine + + PodLine + Environment.NewLine + + "end" + Environment.NewLine); + } + else if (content.Contains(UnityFrameworkTarget)) + { + content = content.Replace(UnityFrameworkTarget, UnityFrameworkTarget + Environment.NewLine + PodLine); + File.WriteAllText(podfilePath, content); + } + else + { + File.AppendAllText(podfilePath, + Environment.NewLine + + UnityFrameworkTarget + Environment.NewLine + + PodLine + Environment.NewLine + + "end" + Environment.NewLine); + } + + Debug.Log("CrashReport iOS 已写入 Bugly CocoaPods 依赖,请在 Xcode 构建前执行 pod install。"); + } + } +} + +#endif diff --git a/Editor/CrashPostProcessBuildIOS.cs.meta b/Editor/CrashPostProcessBuildIOS.cs.meta new file mode 100644 index 0000000..c3a1087 --- /dev/null +++ b/Editor/CrashPostProcessBuildIOS.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 723804e1f52549b68c68e8c16f02ff90 +timeCreated: 1781265600 diff --git a/Plugins/iOS.meta b/Plugins/iOS.meta new file mode 100644 index 0000000..bbac2a9 --- /dev/null +++ b/Plugins/iOS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eaf538d898ef490593642d0b031c7b85 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/iOS/FoldCCBuglyBridge.mm b/Plugins/iOS/FoldCCBuglyBridge.mm new file mode 100644 index 0000000..8a5a09c --- /dev/null +++ b/Plugins/iOS/FoldCCBuglyBridge.mm @@ -0,0 +1,190 @@ +#import + +#if __has_include() +#import +#define FOLDCC_BUGLY_IOS_AVAILABLE 1 +#else +#define FOLDCC_BUGLY_IOS_AVAILABLE 0 +#endif + +static NSString *FoldCCBuglyString(const char *value) +{ + if (value == NULL) + { + return @""; + } + + NSString *result = [NSString stringWithUTF8String:value]; + return result == nil ? @"" : result; +} + +static NSArray *FoldCCBuglyStackFrames(NSString *stackTrace) +{ + if (stackTrace.length == 0) + { + return @[]; + } + + NSArray *lines = [stackTrace componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; + NSMutableArray *frames = [NSMutableArray arrayWithCapacity:lines.count]; + for (NSString *line in lines) + { + NSString *trimmed = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if (trimmed.length > 0) + { + [frames addObject:trimmed]; + } + } + + return frames; +} + +static NSDictionary *FoldCCBuglyExtraInfo(NSString *extras) +{ + if (extras.length == 0) + { + return @{}; + } + + NSData *data = [extras dataUsingEncoding:NSUTF8StringEncoding]; + id parsed = data == nil ? nil : [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; + if ([parsed isKindOfClass:[NSDictionary class]]) + { + return parsed; + } + + return @{ @"UnityExtraInfo" : extras }; +} + +#if FOLDCC_BUGLY_IOS_AVAILABLE +static NSString *s_channel = nil; +static NSString *s_version = nil; +static NSString *s_user = nil; +static NSString *s_deviceId = nil; +static BOOL s_debugMode = NO; +static BOOL s_initialized = NO; + +static BuglyLogLevel FoldCCBuglyLogLevel(int level) +{ + switch (level) + { + case 1: + return BuglyLogLevelError; + case 2: + return BuglyLogLevelWarn; + case 3: + return BuglyLogLevelInfo; + case 4: + return BuglyLogLevelDebug; + default: + return BuglyLogLevelSilent; + } +} +#endif + +extern "C" +{ + void _BuglyInit(const char *appId, bool debug, int level) + { +#if FOLDCC_BUGLY_IOS_AVAILABLE + if (s_initialized) + { + return; + } + + BuglyConfig *config = [[BuglyConfig alloc] init]; + config.debugMode = debug; + config.reportLogLevel = FoldCCBuglyLogLevel(level); + config.channel = s_channel; + config.version = s_version; + config.deviceIdentifier = s_deviceId; + config.consolelogEnable = debug; + [Bugly startWithAppId:FoldCCBuglyString(appId) config:config]; + + if (s_user.length > 0) + { + [Bugly setUserIdentifier:s_user]; + } + + s_debugMode = debug; + s_initialized = YES; +#endif + } + + void _BuglySetUserId(const char *userId) + { +#if FOLDCC_BUGLY_IOS_AVAILABLE + NSString *value = FoldCCBuglyString(userId); + s_user = [value copy]; + if (s_initialized && value.length > 0) + { + [Bugly setUserIdentifier:value]; + } +#endif + } + + void _BuglySetTag(int tag) + { +#if FOLDCC_BUGLY_IOS_AVAILABLE + if (s_initialized) + { + [Bugly setTag:(NSUInteger)tag]; + } +#endif + } + + void _BuglySetKeyValue(const char *key, const char *value) + { +#if FOLDCC_BUGLY_IOS_AVAILABLE + NSString *keyString = FoldCCBuglyString(key); + if (s_initialized && keyString.length > 0) + { + [Bugly setUserValue:FoldCCBuglyString(value) forKey:keyString]; + } +#endif + } + + void _BuglyReportException(int type, const char *name, const char *reason, const char *stackTrace, const char *extras, bool quit) + { +#if FOLDCC_BUGLY_IOS_AVAILABLE + if (s_initialized) + { + [Bugly reportExceptionWithCategory:(NSUInteger)type + name:FoldCCBuglyString(name) + reason:FoldCCBuglyString(reason) + callStack:FoldCCBuglyStackFrames(FoldCCBuglyString(stackTrace)) + extraInfo:FoldCCBuglyExtraInfo(FoldCCBuglyString(extras)) + terminateApp:quit]; + } +#endif + } + + void _BuglyDefaultConfig(const char *channel, const char *version, const char *user, const char *deviceId) + { +#if FOLDCC_BUGLY_IOS_AVAILABLE + s_channel = [FoldCCBuglyString(channel) copy]; + s_version = [FoldCCBuglyString(version) copy]; + s_user = [FoldCCBuglyString(user) copy]; + s_deviceId = [FoldCCBuglyString(deviceId) copy]; +#endif + } + + void _BuglyLogMessage(int level, const char *tag, const char *log) + { +#if FOLDCC_BUGLY_IOS_AVAILABLE + if (s_initialized) + { + [BuglyLog level:FoldCCBuglyLogLevel(level) tag:FoldCCBuglyString(tag) log:@"%@", FoldCCBuglyString(log)]; + } +#endif + } + + void _BuglyConfigCrashReporterType(int type) + { + } + + void _BuglySetExtraConfig(const char *key, const char *value) + { + _BuglySetKeyValue(key, value); + } +} diff --git a/Plugins/iOS/FoldCCBuglyBridge.mm.meta b/Plugins/iOS/FoldCCBuglyBridge.mm.meta new file mode 100644 index 0000000..d8b2a03 --- /dev/null +++ b/Plugins/iOS/FoldCCBuglyBridge.mm.meta @@ -0,0 +1,34 @@ +fileFormatVersion: 2 +guid: 50f7f5117f28421589a4ea87b6824291 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json index 1519031..7a34148 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "com.foldcc.cc-framework.crashreport", "displayName": "CC-Framework.CrashReport", "description": "Crash检测, 异常上报", - "version": "1.0.1", - "unity": "2022.1", + "version": "1.0.2", + "unity": "2022.3", "license": "MIT", "repository": { "type": "git",