福利!适用友盟dSym错误分析的源代码!方便!
点击操作说明:
1.如果没有填写左边的输入框,那么将左边需要填写的相关内容字符串输入右侧框则会读取出需要的值填入左侧
2.如果左侧数据已经填写完成,那么就会根据填入数据输出分析结果到右侧
#import "ViewController.h" @interface ViewController () @property(nonatomic,strong)NSScrollView *contentView; @property(nonatomic,strong)NSTextView *resultView; @property(nonatomic,strong)NSTextField *uuidField; @property(nonatomic,strong)NSTextField *typeField; @property(nonatomic,strong)NSTextField *errorField; @property(nonatomic,strong)NSTextField *slideField; @property(nonatomic,strong)NSTextField *baseField; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSTextField *uuidField = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(10, 10, 300, 30))]; [uuidField setPlaceholderString:@"UUID"]; [self.view addSubview:uuidField]; NSTextField *typeField = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(10, uuidField.frame.origin.y + uuidField.frame.size.height + 10, 300, 30))]; [typeField setPlaceholderString:@"CPU Type"]; [self.view addSubview:typeField]; NSTextField *errorField = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(10, typeField.frame.origin.y + typeField.frame.size.height + 10, 300, 30))]; [errorField setPlaceholderString:@"Error Address"]; [self.view addSubview:errorField]; NSTextField *slideField = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(10, errorField.frame.origin.y + errorField.frame.size.height + 10, 300, 30))]; [slideField setPlaceholderString:@"Slide Address"]; [self.view addSubview:slideField]; NSTextField *baseField = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(10, slideField.frame.origin.y + slideField.frame.size.height + 10, 300, 30))]; [baseField setPlaceholderString:@"Base Address"]; [self.view addSubview:baseField]; NSButton *submit = [NSButton buttonWithTitle:@"生成命令" target:self action:@selector(checkoutCommendText)]; [submit setFrame:NSRectFromCGRect(CGRectMake(10, baseField.frame.origin.y + baseField.frame.size.height + 10, 300, 30))]; [self.view addSubview:submit]; self.contentView = [[NSScrollView alloc] initWithFrame:NSRectFromCGRect(CGRectMake(baseField.frame.origin.x + baseField.frame.size.width + 10, 10, 500, submit.frame.origin.y + submit.frame.size.height))]; self.resultView = [[NSTextView alloc] initWithFrame:self.contentView.bounds]; [self.resultView setMinSize:NSSizeFromCGSize(self.resultView.frame.size)]; [self.resultView setMaxSize:NSSizeFromCGSize(CGSizeMake(self.resultView.frame.size.width, CGFLOAT_MAX))]; [self.resultView.textContainer setContainerSize:NSSizeFromCGSize(CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX))]; [self.resultView.textContainer setWidthTracksTextView:YES]; [self.resultView setVerticallyResizable:YES]; [self.resultView setHorizontallyResizable:NO]; [self.resultView setAutoresizingMask:NSViewWidthSizable]; [self.contentView setHasVerticalScroller:YES]; [self.contentView setHasHorizontalScroller:NO]; [self.contentView setAutoresizingMask:NSViewHeightSizable]; [self.contentView setDocumentView:self.resultView]; [self.view addSubview:self.contentView]; self.uuidField = uuidField; self.typeField = typeField; self.errorField = errorField; self.slideField = slideField; self.baseField = baseField; // Do any additional setup after loading the view. [self.view.window setMinSize:NSMakeSize(920, 458)]; [self.view.window setMaxSize:NSMakeSize(920, 458)]; } -(void)readInfoFromString:(NSString*)string { if (self.uuidField.stringValue.length <= 0 && self.typeField.stringValue.length <= 0 && self.slideField.stringValue.length <= 0 && self.baseField.stringValue.length <= 0) { NSString *uuid = [self findString:string forTypeText:@"dSYM UUID:"]; NSString *type = [self findString:string forTypeText:@"CPU Type:"]; NSString *slide = [self findString:string forTypeText:@"Slide Address:"]; NSString *base = [self findString:string forTypeText:@"Base Address:"]; [self.uuidField setStringValue:uuid]; [self.typeField setStringValue:type]; [self.slideField setStringValue:slide]; [self.baseField setStringValue:base]; } } -(NSString*)findString:(NSString*)string forTypeText:(NSString*)typePrefix { NSInteger startIndex = NSMaxRange([string rangeOfString:typePrefix]); NSInteger endIndex = startIndex; BOOL hasFindStart = NO; for (NSInteger index = startIndex; index < string.length; index++) { NSString *iStr = [string substringWithRange:NSMakeRange(index, 1)]; if ([iStr isEqualToString:@" "] && !hasFindStart) { continue; } else { if (!hasFindStart) { startIndex = index; endIndex = startIndex; hasFindStart = YES; } if ([iStr isEqualToString:@"\n"] || [iStr isEqualToString:@"\r"] || [iStr isEqualToString:@"\r\n\n"] || [iStr isEqualToString:@" "] || [iStr isEqualToString:@"\t"] || (index == (string.length - 1))) { if (startIndex == endIndex && startIndex == index) { endIndex = startIndex - 1; } else { if (index == (string.length - 1)) { endIndex = index; } else { endIndex = index - 1; } } break; } } } if (hasFindStart) { if (endIndex >= startIndex) { return [string substringWithRange:NSMakeRange(startIndex, endIndex - startIndex + 1)]; } } return @""; } -(void)checkoutCommendText { if (self.resultView.string.length > 0 && self.errorField.stringValue.length <= 0) { [self readInfoFromString:self.resultView.string]; [self.resultView setString:@""]; } else { [self.resultView setString:@""]; NSString *formatter = @"dSYMPath=\"$(find ~/Library/Developer/Xcode -iname '*.dSYM' -print0 | xargs -0 dwarfdump -u | grep %@ | sed -E 's/^[^/]+//' | head -n 1)\";dwarfdump --arch=%@ --lookup 0x%lx \"$dSYMPath\""; NSString *uuid = self.uuidField.stringValue; NSString *type = self.typeField.stringValue; NSInteger error = [self intFrom16String:self.errorField.stringValue]; NSInteger slide = [self intFrom16String:self.slideField.stringValue]; NSInteger base = [self intFrom16String:self.baseField.stringValue]; NSString *code = [NSString stringWithFormat:formatter,uuid,type,(error - base + slide)]; NSLog(@"%@",code); [self.resultView setString:[self runCommand:code]]; } } - (NSString *)runCommand:(NSString *)commandToRun { NSTask *task = [[NSTask alloc] init]; [task setLaunchPath:@"/bin/sh"]; NSArray *arguments = @[@"-c", [NSString stringWithFormat:@"%@", commandToRun]]; // NSLog(@"run command:%@", commandToRun); [task setArguments:arguments]; NSPipe *pipe = [NSPipe pipe]; [task setStandardOutput:pipe]; NSFileHandle *file = [pipe fileHandleForReading]; [task launch]; NSData *data = [file readDataToEndOfFile]; NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return output; } -(NSInteger)intFrom16String:(NSString*)string { NSInteger i = 0; NSArray *iArr = @[@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"A",@"B",@"C",@"D",@"E",@"F"]; BOOL hasStart = NO; for (NSInteger index = 0; index < string.length; index++) { if (index >= 0 ) { NSString *iStr = [[string substringWithRange:NSMakeRange(index, 1)] uppercaseString]; if (!hasStart && (![iArr containsObject:iStr] || [iStr isEqualToString:@"0"])) { continue; } else if([iArr containsObject:iStr]) { hasStart = YES; i = (i * 16) + [iArr indexOfObject:iStr]; } } } return i; } - (void)setRepresentedObject:(id)representedObject { [super setRepresentedObject:representedObject]; // Update the view, if already loaded. } @end