summaryrefslogtreecommitdiff
path: root/common/foundation_request.mm
diff options
context:
space:
mode:
Diffstat (limited to 'common/foundation_request.mm')
-rw-r--r--common/foundation_request.mm63
1 files changed, 63 insertions, 0 deletions
diff --git a/common/foundation_request.mm b/common/foundation_request.mm
new file mode 100644
index 0000000000..d7ab26cefa
--- /dev/null
+++ b/common/foundation_request.mm
@@ -0,0 +1,63 @@
+#import <Foundation/Foundation.h>
+#include <memory>
+#include <string>
+#include <functional>
+#include <llmr/platform/platform.hpp>
+
+
+namespace llmr {
+
+class platform::Request {
+public:
+ Request(NSURLSessionDataTask *task, const std::string &original_url)
+ : task(task), original_url(original_url) {}
+ NSURLSessionDataTask *task;
+ std::string original_url;
+};
+
+std::shared_ptr<platform::Request>
+platform::request_http(const std::string &url, std::function<void(Response *)> background_function,
+ std::function<void()> foreground_callback) {
+ __block std::shared_ptr<Request> req;
+ NSURLSessionDataTask *task = [[NSURLSession sharedSession]
+ dataTaskWithURL:[NSURL URLWithString:@(url.c_str())]
+ completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
+ // Make sure we clear the shared_ptr to resolve the circular reference. We're referencing
+ // this shared_ptr by value so that the object stays around until this completion handler is
+ // invoked.
+ req.reset();
+
+ if ([error code] == NSURLErrorCancelled) {
+ // We intentionally cancelled this request. Do nothing.
+ return;
+ }
+
+ Response res;
+
+ if (!error && [response isKindOfClass:[NSHTTPURLResponse class]]) {
+ res.code = [(NSHTTPURLResponse *)response statusCode];
+ res.body = {(const char *)[data bytes], [data length]};
+ } else {
+ res.code = -1;
+ res.error_message = [[error localizedDescription] UTF8String];
+ }
+
+ background_function(&res);
+
+ dispatch_async(dispatch_get_main_queue(), ^(void) {
+ foreground_callback();
+ });
+ }];
+
+ req = std::make_shared<Request>(task, url);
+ [task resume];
+ return req;
+}
+
+void platform::cancel_request_http(const std::shared_ptr<Request> &req) {
+ if (req) {
+ [req->task cancel];
+ }
+}
+
+}