ios - 如何通过 objective-c 中的 POST 请求捕获 stderr 输出并将消息发送到远程日志文件?

标签 ios objective-c

我有一个简单的网络服务在线监听发布请求。它会将发送给它的字符串作为正文中的参数写入本地文件。

现在,我有一个 iOS 应用程序,我想将应用程序的 stderr 的每条消息发送到 Web 服务,以在在线文件上记录错误,并能够实时远程查看应用程序错误。

我知道我可以像这样将 stderr 消息重定向到一个文件(设备本地)

+ (void) redirectNSLogToDocuments {
    NSArray *allPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [allPaths objectAtIndex:0];
    NSString *pathForLog = [documentsDirectory stringByAppendingPathComponent:@"errLog.txt"];
    freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}

我知道我可以像这样发送 post 请求,所以将字符串 'errorString' 写入远程日志

    NSString *errorString=@"errorIOS";
    NSString *errorData =[NSString stringWithFormat:@"errorString=%@",errorString];
    NSData *postData = [errorData dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:@"http://mywebserviceurl"]];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

但是,如果我想重定向 stderr 消息,以便每次引发错误消息时,它都会触发对我的 Web 服务的发布请求,并将消息写入远程日志,而不是写入设备本地文件?

最佳答案

使用此代码可以捕获附加管道的 stderr

NSPipe* pipe = [NSPipe pipe];
NSFileHandle* pipeReadHandle = [pipe fileHandleForReading];
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stderr));
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, [pipeReadHandle fileDescriptor], 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(source, ^{
    void* data = malloc(4096);
    ssize_t readResult = 0;
    do
    {
        errno = 0;
        readResult = read([pipeReadHandle fileDescriptor], data, 4096);
    } while (readResult == -1 && errno == EINTR);
    if (readResult > 0)
    {
        //AppKit UI should only be updated from the main thread
        dispatch_async(dispatch_get_main_queue(),^{
            NSString* stdOutString = [[NSString alloc] initWithBytesNoCopy:data length:readResult encoding:NSUTF8StringEncoding freeWhenDone:YES];
            NSAttributedString* stdOutAttributedString = [[NSAttributedString alloc] initWithString:stdOutString];
            [appFunctions postDataToRemoteLogWithMessage:stdOutAttributedString];
        });
    }
    else{free(data);}
});
dispatch_resume(source);

所以加上函数,可以实现结果

+ (NSString *) postDataToRemoteLogWithMessage:(NSString *)errorString{
    // Send post request to webservice
    NSString *errorData =[NSString stringWithFormat:@"errorString=%@",errorString];
    NSData *postData = [errorData dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:@"http://mywebserviceurl"]];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if(conn) {
        //NSLog(@"Connection Successful");
    } else {
        //NSLog(@"Connection could not be made");
    }
}

关于ios - 如何通过 objective-c 中的 POST 请求捕获 stderr 输出并将消息发送到远程日志文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54145688/

相关文章:

objective-c - 在 Objective-C 中生成随机数

c++ - 在 Objective-C 中转发声明 C++ 类

iphone - 在 iPhone 上拆分字符串前缀的数字

ios - 如何向 subview 显示动画,因为它出现在 UIViewController 中

ios - 如何访问自定义类属性作为引用 socket ?

iOS:在 xml 解析完成之前创建 TableView

iOS 应用内购买验证

ios - 如何在 iOS 上评估 x509 证书的信任度

c# - 使用手机时需要从网站推荐手机应用商店链接

ios - 如何找出SQLITE查询结果为NULL?