macOS开发中网络连接或数据库连接收到错误“Operation not permitted”的解决方法

本文介绍了在macOS Cocoa工程中遇到的网络请求失败问题及其解决方法。通过启用App Sandbox中的网络权限,解决了无法访问本地PHP文件及数据库的难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    在给出解决方案之前,我一定要好好吐槽吐槽,网上对于原生态的macOS开发的资料实在实在是太少了,关于这方面的问题在网上怎么搜都搜不出来,唯一的参考资料就是苹果开发者官网,但是对于我们大多数英语不是很好的开发者来说,阅读起来难度太大,而且,针对一些配置之类很细节的问题,在上面又没办法定位到,因为它只给出的是每个模块如何使用,却没有给出在什么样的场景下遇到什么样的问题应该如何解决。

    如果我们创建了一个macOS平台的Cocoa工程(无论是OC还是Swift),如果在其中添加了和网络请求相关的代码,例如访问网络上的一个PHP,或是连接网络上的一个MySQL数据库(哪怕这个PHP或数据库是本地的,其实都还是需要经过网络的,除非你是文件型的嵌入式数据库或者是Python脚本)。例如,我想访问localhost上的test.php文件,我可以给出如下代码:

NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/test.php"];
    [[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (!data) {return;}
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@", str);
    }] resume];

或是Swift中的:

let url = URL(string: "http://127.0.0.1/test.php")
        URLSession.shared.dataTask(with: url!) { (data, res, err) in
            if data == nil {return}
            let str = String(data: data!, encoding: .utf8)
            print(str!)
        }.resume()

都会得到类似于如下的报错信息:

2018-04-25 13:06:44.780391+0800 test2[2124:87764] [] nw_socket_connect connectx failed (fd 12, 127.0.0.1:80 stream, pid: 2124, url: http://127.0.0.1/test.php) [1: Operation not permitted]
2018-04-25 13:06:44.780447+0800 test2[2124:87764] [] nw_socket_get_input_frames recvmsg(fd 12, 1024 bytes) [57: Socket is not connected]
2018-04-25 13:06:44.780610+0800 test2[2124:87764] TIC TCP Conn Failed [1:0x604000164380]: 1:57 Err(57)
2018-04-25 13:06:44.781281+0800 test2[2124:87764] Task <45191EF4-F0FE-4B58-BE07-7394D072C659>.<1> HTTP load failed (error code: -1005 [1:57])
2018-04-25 13:06:44.781422+0800 test2[2124:87756] Task <45191EF4-F0FE-4B58-BE07-7394D072C659>.<1> finished with error - code: -1005

    而让人非常抓狂的是,如果你创建的是一个控制台项目,或者是一个iOS项目,一模一样的代码都是可以执行成功的。所以,这显然是工程项目配置的问题所导致。

    在网上如果查询类似的问题,清一色都只会给你关于修改info.plist中App Transport Security Settings项来启动http协议的支持。但这仅仅是对于iOS项目有效的方法,对于macOS项目是不起作用的。

    更可气的是,这个问题还没有办法绕过。我曾经尝试过很多种方法,其中有一种的思路是,写一个Python脚本,在Python脚本内进行网络连接,然后在macOS项目中其中这个Python脚本,实现间接访问网络的方法。但这个方法也是没有作用的,因为项目本身没有网络访问的权限,那么通过这个程序所启动的脚本也同样没有这个权限。而且不仅限于脚本,哪怕是启动另一个控制台程序,也同样不具有这个权限。

    其实,这是苹果对于权限的控制机制,我们想出的这些所谓“绕行”方法恰巧也是有些电脑病毒所采取的方法,那当然是要被封堵的。因此,要想解决这个问题,还是要回归本质,找到在工程设置中此项的位置,然后开启网络操作的权限开关。

    其实,这个问题特别好解决(就是这个位置太难找),解决的方法是这样的,如下图所示:

    首先,进入工程配置界面,然后打开Capability标签,里面有一项App Sandbox,我们需要开启这个控制项。注意,如果这个控制项被开启,你的项目就不能是无组织的项目,你必须要和你的一个开发者账号相帮定,如果你在开启的时候还没有选择Team,就会弹出窗口让你选择一个Team,如果已经选择的就不会显示(可以在General中进行相关设置)。

    在展开的App Sandbox中有network这一项,后面有两个复选框,一个用于允许接收数据,一个用于允许发送数据,这个请根据自己的实际情况进行开启。

    当开启这个选项之后,网络请求就被允许了,也就可以访问到PHP文件、数据库这些网络位置了。而本人亲测,info.plist中App Transport Security Settings的项目似乎对此并没有影响,http协议的URL也可以照常访问。

    上述都在环境为macOS 10.13.4中Xcode 9.3中进行,还并不能确定是否适用于其他环境(但是本人猜测,应该都是适用的)。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

borehole打洞哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值