Skip to content

Commit

Permalink
Support file download
Browse files Browse the repository at this point in the history
  • Loading branch information
brianquinlan committed Oct 10, 2024
1 parent db3a9fc commit 95880e4
Show file tree
Hide file tree
Showing 7 changed files with 318 additions and 36 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#import <Foundation/NSLock.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSURLSession.h>
#include <stdint.h>

#if !__has_feature(objc_arc)
#error "This file must be compiled with ARC enabled"
#endif

typedef void (^_DidFinish)(void *, NSURLSession *session,
NSURLSessionDownloadTask *downloadTask,
NSURL *location);
typedef void (^_DidFinishWithLock)(NSCondition *lock, NSURLSession *session,
NSURLSessionDownloadTask *downloadTask,
NSURL *location);
/// Create a block useable as a
/// `URLSession:downloadTask:didFinishDownloadingToURL:` that can be used to
/// make an async Dart callback behave synchronously.
_DidFinish adaptFinishWithLock(_DidFinishWithLock block);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import "utils.h"

_DidFinish adaptFinishWithLock(_DidFinishWithLock block) {
return ^void(void *, NSURLSession *session,
NSURLSessionDownloadTask *downloadTask, NSURL *location) {
NSCondition *lock = [[NSCondition alloc] init];

[lock lock];
block(lock, session, downloadTask, location);
[lock lock];
[lock unlock];
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ void testOnFinishedDownloading(URLSessionConfiguration Function() config) {
expect(actualContent, 'Hello World');
session.finishTasksAndInvalidate();
});
}, skip: 'XXX will not work with current approach');
});
}

void testOnRedirect(URLSessionConfiguration Function() config) {
Expand Down
5 changes: 1 addition & 4 deletions pkgs/cupertino_http/ffigen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ headers:
- '/System/Volumes/Data/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSOperation.h'
- '/System/Volumes/Data/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSError.h'
- '/System/Volumes/Data/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSDictionary.h'
# - 'src/CUPHTTPClientDelegate.h'
# - 'src/CUPHTTPForwardedDelegate.h'
# - 'src/CUPHTTPCompletionHelper.h'
- 'darwin/cupertino_http/Sources/cupertino_http/CUPHTTPStreamToNSInputStreamAdapter.h'
- 'darwin/cupertino_http/Sources/cupertino_http/utils.h'
preamble: |
// ignore_for_file: always_specify_types
// ignore_for_file: camel_case_types
Expand Down
29 changes: 21 additions & 8 deletions pkgs/cupertino_http/lib/src/cupertino_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -911,15 +911,28 @@ class URLSession extends _ObjectHolder<ncb.NSURLSession> {
}

if (onFinishedDownloading != null) {
ncb.NSURLSessionDownloadDelegate.addToBuilderAsListener(protoBuilder,
URLSession_downloadTask_didFinishDownloadingToURL_:
(nsSession, nsTask, nsUrl) {
onFinishedDownloading(
URLSession._(nsSession,
isBackground: isBackground, hasDelegate: true),
URLSessionDownloadTask._(nsTask),
nsurlToUri(nsUrl));
final asyncFinishDownloading =
ncb.ObjCBlock_ffiVoid_NSCondition_NSURLSession_NSURLSessionDownloadTask_NSURL
.listener((nsCondition, nsSession, nsTask, nsUrl) {
try {
onFinishedDownloading(
URLSession._(nsSession,
isBackground: isBackground, hasDelegate: true),
URLSessionDownloadTask._(nsTask),
nsurlToUri(nsUrl));
} finally {
nsCondition.unlock();
}
});

final downloadDelegate = objc.getProtocol('NSURLSessionDownloadDelegate');
final didFinishDownloadingToURL = objc
.registerName('URLSession:downloadTask:didFinishDownloadingToURL:');
final signature = objc.getProtocolMethodSignature(
downloadDelegate, didFinishDownloadingToURL,
isRequired: true, isInstanceMethod: true);
protoBuilder.implementMethod(didFinishDownloadingToURL, signature,
linkedLibs.adaptFinishWithLock(asyncFinishDownloading));
}

if (onWebSocketTaskOpened != null) {
Expand Down
Loading

0 comments on commit 95880e4

Please sign in to comment.