Browse Source

1.修改iOS Apex Drivers Navigation 增加异常捕获。

Pen Li 7 năm trước cách đây
mục cha
commit
ccf1b56719

+ 14 - 0
Redant Drivers/Apex And Drivers.xcodeproj/project.pbxproj

@@ -132,6 +132,7 @@
 		4281100520E4D47000315156 /* UIView+JLExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 4281100020E4D46F00315156 /* UIView+JLExtension.m */; };
 		429CF61C20E0E32E00CE8DAD /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 429CF61E20E0E32E00CE8DAD /* Localizable.strings */; };
 		42C1B2742134F24C00637085 /* RADatePickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 42C1B2732134F24C00637085 /* RADatePickerViewController.m */; };
+		42C6074C21536E5A003E5379 /* RAExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 42C6074B21536E59003E5379 /* RAExceptionHandler.m */; };
 		42D187802140BACC00C822C0 /* RAEditRequiredAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 42D1877F2140BACC00C822C0 /* RAEditRequiredAlert.m */; };
 		42D7B07121478D9C0046FE89 /* new_message.png in Resources */ = {isa = PBXBuildFile; fileRef = 42D7B07021478D9B0046FE89 /* new_message.png */; };
 		42D7B0762147945C0046FE89 /* RASettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 42D7B0752147945C0046FE89 /* RASettingViewController.m */; };
@@ -439,6 +440,8 @@
 		429CF61F20E0E35D00CE8DAD /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
 		42C1B2722134F24C00637085 /* RADatePickerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RADatePickerViewController.h; sourceTree = "<group>"; };
 		42C1B2732134F24C00637085 /* RADatePickerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RADatePickerViewController.m; sourceTree = "<group>"; };
+		42C6074A21536E59003E5379 /* RAExceptionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAExceptionHandler.h; sourceTree = "<group>"; };
+		42C6074B21536E59003E5379 /* RAExceptionHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAExceptionHandler.m; sourceTree = "<group>"; };
 		42D1877E2140BACC00C822C0 /* RAEditRequiredAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RAEditRequiredAlert.h; sourceTree = "<group>"; };
 		42D1877F2140BACC00C822C0 /* RAEditRequiredAlert.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RAEditRequiredAlert.m; sourceTree = "<group>"; };
 		42D7B07021478D9B0046FE89 /* new_message.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = new_message.png; sourceTree = "<group>"; };
@@ -1008,6 +1011,15 @@
 			path = DatePicker;
 			sourceTree = "<group>";
 		};
+		42C6074921536E59003E5379 /* ExceptionHandler */ = {
+			isa = PBXGroup;
+			children = (
+				42C6074A21536E59003E5379 /* RAExceptionHandler.h */,
+				42C6074B21536E59003E5379 /* RAExceptionHandler.m */,
+			);
+			path = ExceptionHandler;
+			sourceTree = "<group>";
+		};
 		42D1877D2140BA7000C822C0 /* RequiredAlertVC */ = {
 			isa = PBXGroup;
 			children = (
@@ -1251,6 +1263,7 @@
 		71EAA33020B9571B002F003C /* Apex And Drivers */ = {
 			isa = PBXGroup;
 			children = (
+				42C6074921536E59003E5379 /* ExceptionHandler */,
 				42DFE267213F81F8000213C2 /* EmptyView */,
 				42DFE260213F80AF000213C2 /* UIScrollVIew+Empty */,
 				422DA1BD2134FA510021BD70 /* PresentationController */,
@@ -1530,6 +1543,7 @@
 				424204DC20C61561005AEED9 /* RAQRCodeScannerViewController.m in Sources */,
 				42D8B8D520C27399001C125F /* RADetailActionsCell+CollectionViewDelegate.m in Sources */,
 				424204E720C668AE005AEED9 /* RATakePhotoPreviewController.m in Sources */,
+				42C6074C21536E5A003E5379 /* RAExceptionHandler.m in Sources */,
 				42810FEE20E4C93400315156 /* RAHomeMoreViewController+TableDataSource.m in Sources */,
 				4205FD6C20C13E0700DB42B4 /* RAHomeViewController+HomeTableDelegate.m in Sources */,
 				4235FA9A213E0CE9000B6672 /* RADetailMapCell.m in Sources */,

+ 6 - 0
Redant Drivers/Apex And Drivers/AppDelegate.m

@@ -11,6 +11,7 @@
 #import "RAHomeViewController.h"
 #import <CoreLocation/CoreLocation.h>
 #import "RANavigationController.h"
+#import "RAExceptionHandler.h"
 
 @interface AppDelegate ()<UNUserNotificationCenterDelegate,CLLocationManagerDelegate>
 
@@ -114,6 +115,11 @@
 //
 //    }
     
+    [RAExceptionHandler registHandler:^(NSString *exceptionStr) {
+       
+        NSLog(@"Exception:\n%@",exceptionStr);
+        
+    }];
     
     
     // View

+ 18 - 0
Redant Drivers/Apex And Drivers/ExceptionHandler/RAExceptionHandler.h

@@ -0,0 +1,18 @@
+//
+//  LPExceptionHandler.h
+//  Mach-O UUID
+//
+//  Created by Jack on 2018/8/1.
+//  Copyright © 2018年 emerys. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/**
+ * @brief 收集Crash信息,分析参考https://github.com/answer-huang/dSYMTools
+ */
+@interface RAExceptionHandler : NSObject
+
++ (void)registHandler:(void (^)(NSString *exceptionStr)) handler;
+
+@end

+ 227 - 0
Redant Drivers/Apex And Drivers/ExceptionHandler/RAExceptionHandler.m

@@ -0,0 +1,227 @@
+//
+//  LPExceptionHandler.m
+//  Mach-O UUID
+//
+//  Created by Jack on 2018/8/1.
+//  Copyright © 2018年 emerys. All rights reserved.
+//
+
+#import "RAExceptionHandler.h"
+#import <UIKit/UIDevice.h>
+#import <sys/utsname.h>
+
+// Mach-O UUID
+#import <mach-o/ldsyms.h>
+
+// CPU arch
+#import <mach-o/arch.h>
+
+// Slide Address
+#include <mach-o/dyld.h>
+
+@interface RAExceptionHandler ()
+
+@property (nonatomic,copy) void (^handler)(NSString *);
+
++ (instancetype)sharedHanlder;
+
+@end
+
+#pragma mark - dSYM UUID
+
+// 获取主执行Image UUID,此UUID要和dSYM文件UUID相同
+NSString *mach_oUUID() {
+    const uint8_t *command = (const uint8_t *)(&_mh_execute_header + 1);
+    for (uint32_t idx = 0; idx < _mh_execute_header.ncmds; ++idx) {
+        if (((const struct load_command *)command)->cmd == LC_UUID) {
+            command += sizeof(struct load_command);
+//            return [NSString stringWithFormat:@"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+//                    command[0], command[1], command[2], command[3],
+//                    command[4], command[5],
+//                    command[6], command[7],
+//                    command[8], command[9],
+//                    command[10], command[11], command[12], command[13], command[14], command[15]];
+            
+            CFUUIDRef uuidRef = CFUUIDCreateFromUUIDBytes(NULL, *((CFUUIDBytes*)command));
+            NSString* uuidStr = (__bridge_transfer NSString*)CFUUIDCreateString(NULL, uuidRef);
+            
+            return uuidStr;
+            
+        } else {
+            command += ((const struct load_command *)command)->cmdsize;
+        }
+    }
+    return nil;
+}
+
+#pragma mark - CPU Type
+
+const char *byteOrder(enum NXByteOrder BO) {
+    switch (BO) {
+        case NX_LittleEndian: return ("Little-Endian");
+        case NX_BigEndian: return ("Big-Endian");
+        case NX_UnknownByteOrder: return "Unknow";
+        default: return ("!?!");
+    }
+}
+
+void testGetAllArch () {
+    
+    const NXArchInfo *known = NXGetAllArchInfos();
+    
+    while (known && known->description) {
+        printf("known: %s\t%x/%x\t%s\n", known->description,
+               known->cputype,
+               known->cpusubtype,
+               byteOrder(known->byteorder));
+        known++;
+    }
+}
+
+// 获取CPU架构类型
+NSString *localCPUType() {
+    const NXArchInfo *local = NXGetLocalArchInfo();
+    
+    
+    if (local) {
+        printf("Local - %s\t%x/%x\t%s\n", local->description,
+               local->cputype,
+               local->cpusubtype,
+               byteOrder(local->byteorder));
+        
+        return [NSString stringWithUTF8String:local->description];
+    }
+    return @"unknown";
+}
+
+#pragma mark - Slide Address
+
+//获取基地址
+uintptr_t loadAddress() {
+    const struct mach_header *exe_header = NULL;
+    for (uint32_t i = 0; i < _dyld_image_count(); i++) {
+        const struct mach_header *header = _dyld_get_image_header(i);
+        if (header->filetype == MH_EXECUTE) {
+            exe_header = header;
+            break;
+        }
+    }
+    
+    //返回值即为加载地址
+    return (uintptr_t)exe_header;
+}
+
+// 获取偏移地址
+uintptr_t slideAddress() {
+    
+    uintptr_t vmaddr_slide = 0;
+    for (uint32_t i = 0; i < _dyld_image_count(); i++) {
+        const struct mach_header *header = _dyld_get_image_header(i);
+        if (header->filetype == MH_EXECUTE) {
+            vmaddr_slide = _dyld_get_image_vmaddr_slide(i);
+            break;
+        }
+    }
+    
+    return (uintptr_t)vmaddr_slide;
+}
+
+#pragma mark - Binary Image
+
+NSString *binaryImageName() {
+    
+    for (uint32_t i = 0; i < _dyld_image_count(); i++) {
+        const struct mach_header *header = _dyld_get_image_header(i);
+        if (header->filetype == MH_EXECUTE) {
+            
+            const char *path = _dyld_get_image_name((unsigned)i);
+            NSString *imagePath = [NSString stringWithUTF8String:path];
+            NSArray *array = [imagePath componentsSeparatedByString:@"/"];
+            NSString *imageName = array[array.count - 1];
+            return imageName;
+            
+            break;
+        }
+    }
+    
+    return nil;
+}
+
+#pragma mark - Caught Exception
+
+void UncaughtExceptionHandler(NSException *exception) {
+    
+    NSMutableString *exceptionStr = [NSMutableString string];
+    
+    UIDevice *device = [UIDevice currentDevice];
+    NSString *modle = device.model;
+    NSString *os = device.systemName;
+    NSString *ver = device.systemVersion;
+    
+    struct utsname systeminfo;
+    uname(&systeminfo);
+    NSString *deviceString = [NSString stringWithCString:systeminfo.machine encoding:NSUTF8StringEncoding];
+    
+    [exceptionStr appendFormat:@"Device: %@\n",modle];
+    [exceptionStr appendFormat:@"OS: %@ %@\n",os,ver];
+    [exceptionStr appendFormat:@"Hardware: %@\n",deviceString];
+    
+    NSDictionary* infoDict =[[NSBundle mainBundle] infoDictionary];
+    NSString* build =[infoDict objectForKey:@"CFBundleVersion"];
+    NSString* version =[infoDict objectForKey:@"CFBundleShortVersionString"];
+    NSString *bundleID = [infoDict objectForKey:@"CFBundleIdentifier"];
+    NSString *bundleName = [infoDict objectForKey:@"CFBundleName"];
+    
+    [exceptionStr appendFormat:@"Bundle Name: %@\n",bundleName];
+    [exceptionStr appendFormat:@"build: %@\n",build];
+    [exceptionStr appendFormat:@"version: %@\n",version];
+    [exceptionStr appendFormat:@"identifier: %@\n",bundleID];
+    
+    NSDate *date = [NSDate date];
+    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
+    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
+    NSString *dateStr = [formatter stringFromDate:date];
+    
+    [exceptionStr appendFormat:@"Date/Time: %@\n\n",dateStr];
+    
+    NSArray *callStack = [exception callStackSymbols];
+    NSString *reason = [exception reason];
+    NSString *name = [exception name];
+    
+    [exceptionStr appendFormat:@"%@\n%@\n\n%@\n\n",name,reason,callStack];
+    [exceptionStr appendFormat:@"dSYM UUID: %@\n",mach_oUUID()];
+    [exceptionStr appendFormat:@"CPU Type: %@\n",localCPUType()];
+    [exceptionStr appendFormat:@"Slide Address: 0x%lx\n",slideAddress()];
+    [exceptionStr appendFormat:@"Binary Image: %@\n",binaryImageName()];
+    [exceptionStr appendFormat:@"Base Address: 0x%lx\n",loadAddress()];
+    
+    NSLog(@"exception:\n%@",exceptionStr);
+    
+    if ([RAExceptionHandler sharedHanlder].handler) {
+        [RAExceptionHandler sharedHanlder].handler(exceptionStr);
+    }
+}
+
+#pragma mark - Handler
+
+@implementation RAExceptionHandler
+
++ (instancetype)sharedHanlder {
+    static RAExceptionHandler *handler = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        handler = [[RAExceptionHandler alloc] init];
+    });
+    return handler;
+}
+
++ (void)registHandler:(void (^)(NSString *))handler {
+    [[RAExceptionHandler sharedHanlder] registExceptionHandler:handler];
+}
+
+- (void)registExceptionHandler:(void (^)(NSString *))handler {
+    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
+    self.handler = handler;
+}
+
+@end