我正在尝试使用cURL从Cocoa应用程序向我的Yamaha接收器发送POST请求。我正在使用NSTask来实现这一点,并相信我的语法正确:
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"/usr/bin/"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"-c", @"curl -v -X POST -H \"Content-type:text/xml\" --data 'xml=<?xml version=\"1.0\" encoding=\"utf-8\"?><YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>On</Power></Power_Control></Main_Zone></YAMAHA_AV>' http://172.19.24.23/YamahaRemoteControl/ctrl", nil];
[task setArguments: arguments];
[task launch];
我将它分配给我的应用程序中的按钮,它成功编译但是当我按下按钮时我会在日志中得到它。
2013-12-06 11:06:27.907 MyApp[18361:303] user clicked powerOnReceiver button
2013-12-06 11:06:27.909 MyApp[18361:303] Couldn't posix_spawn: error 13
2013-12-06 11:06:27.911 MyApp[18361:303] (
0 CoreFoundation 0x00007fff897c641c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff88e96e75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff897c62cc +[NSException raise:format:] + 204
3 Foundation 0x00007fff87e71214 -[NSConcreteTask launchWithDictionary:] + 3167
4 MyApp 0x0000000100001c9a -[Receiver powerOnReceiver] + 218
5 MyApp 0x0000000100007053 -[AppDelegate powerOnReceiver:] + 67
6 AppKit 0x00007fff863733d0 -[NSApplication sendAction:to:from:] + 327
7 AppKit 0x00007fff8637324e -[NSControl sendAction:to:] + 86
8 AppKit 0x00007fff863bfd7d -[NSCell _sendActionFrom:] + 128
9 AppKit 0x00007fff863d9715 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2316
10 AppKit 0x00007fff863d8ae7 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 487
11 AppKit 0x00007fff863d81fd -[NSControl mouseDown:] + 706
12 AppKit 0x00007fff86359d08 -[NSWindow sendEvent:] + 11296
13 AppKit 0x00007fff862f8744 -[NSApplication sendEvent:] + 2021
14 AppKit 0x00007fff86148a29 -[NSApplication run] + 646
15 AppKit 0x00007fff86133803 NSApplicationMain + 940
16 MyApp 0x00000001000063e2 main + 34
17 libdyld.dylib 0x00007fff85ed05fd start + 1
)
我认为我的路径在这里是正确的,因此我不确定何时收到“无法posix_spawn:错误13”消息。任何想法都将不胜感激。
答案 0 :(得分:5)
错误13是EACCES
(权限被拒绝)。
launchPath
属性应设置可执行文件的路径(此处为curl
),但您已设置其文件夹/usr/bin/
。
其他事项:构建参数列表的方式存在一些问题。由于NSTask
注意在幕后构建正确的argv[]
列表,因此必须注意通过参数来解决问题。
此外,你不应该做额外的报价。换句话说,您必须通过@"Content-type:text/xml"
而不是@"\"Content-type:text/xml\""
。
总结一下,你应该按照以下步骤重写你的任务:
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/curl"];
NSArray *arguments = [NSArray arrayWithObjects:@"-v", @"-X", @"POST",
@"-H", @"Content-type:text/xml",
@"--data", @"xml=<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control>"
"<Power>On</Power></Power_Control></Main_Zone></YAMAHA_AV>",
@"http://172.19.24.23/YamahaRemoteControl/ctrl", nil];
[task setArguments:arguments];
[task launch];
PS。:您有没有理由不使用NSURLConnection
来执行POST
?