В Xcode мое приложение Ma c запускает curl, но -o не может записать на диск - PullRequest
0 голосов
/ 07 апреля 2020

В терминале это работает:

/usr/bin/curl --connect-timeout 10 --max-time 60 https://en.wikipedia.org/wiki/The_Beatles -o /Users/username/Desktop/wikiData

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  909k  100  909k    0     0  2025k      0 --:--:-- --:--:-- --:--:-- 2025k

Но в Xcode это не так:

let task = Process()
let pipe = Pipe()
task.launchPath = "/usr/bin/curl"
task.arguments = ["--connect-timeout","10","--max-time","60","en.wikipedia.org/wiki/The_Beatles","-o","/Users/username/Desktop/wikiData"]
task.standardOutput = pipe
task.launch()
task.waitUntilExit()

Я получаю это:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
Warning: Failed to create the file /Users/username/Desktop/wikiData: 
Warning: Operation not permitted
curl: (23) Failed writing received data to disk/application

Как мне дать скручивать разрешение на запись на диск? В «Песочнице» я проверил «Входящие / исходящие сети», чтобы иметь возможность общаться с Википедией, и установил «Доступ к файлу / Выбранный пользователем файл / Чтение / запись», но это не относится к скручиванию. Если я остановлюсь "-o ...", я не получу ошибку. Но я также, кажется, не получаю данных. Идеи? Благодаря.

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Причина, по которой cURL не может записать вывод, состоит в том, что у него должны быть разрешения, которые песочница не разрешит. Вы, вероятно, должны взять stdout через канал cURL, а затем попытаться написать данные атомарно.

let filePath = "/Users/username/Desktop/wikiData/the_beatles.txt"
let task = Process()

task.launchPath = "/usr/bin/curl"
task.arguments = ["--connect-timeout","10","--max-time","60","https://en.wikipedia.org/wiki/The_Beatles"]

// stdout everything to pipe
let pipe = Pipe()
task.standardOutput = pipe

task.launch()

// collect output
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)

let str = output!
let filename = URL(fileURLWithPath: filePath)

do {
    try str.write(to: filename, atomically: true, encoding: String.Encoding.utf8.rawValue)
} catch {
    print("failed.")
}

Вероятно, есть более чистые способы сделать sh это (например, URLSession), хотя, по крайней мере, это должно дать вам некоторое представление о том, как записывать данные в рамках ограничений изолированного приложения.

0 голосов
/ 07 апреля 2020

Мне пришлось изменить

let filePath = "/Users/username/Desktop/wikiData/the_beatles.txt"

на

let filePath = NSHomeDirectory() + "/wikiData"

Спасибо за вашу помощь; сейчас все работает : -)

...