Browse Source

URL: Allow specifying shared container for downloads on iOS

v6.1.6
reuk 4 years ago
parent
commit
f87582a013
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
7 changed files with 110 additions and 52 deletions
  1. +2
    -2
      modules/juce_core/native/juce_android_Network.cpp
  2. +2
    -2
      modules/juce_core/native/juce_curl_Network.cpp
  3. +2
    -2
      modules/juce_core/native/juce_linux_Network.cpp
  4. +18
    -16
      modules/juce_core/native/juce_mac_Network.mm
  5. +2
    -2
      modules/juce_core/native/juce_win32_Network.cpp
  6. +16
    -8
      modules/juce_core/network/juce_URL.cpp
  7. +68
    -20
      modules/juce_core/network/juce_URL.h

+ 2
- 2
modules/juce_core/native/juce_android_Network.cpp View File

@@ -554,9 +554,9 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
};
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost)
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, const DownloadTaskOptions& options)
{
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost);
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, options);
}
//==============================================================================


+ 2
- 2
modules/juce_core/native/juce_curl_Network.cpp View File

@@ -648,9 +648,9 @@ public:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
};
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost)
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, const DownloadTaskOptions& options)
{
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost);
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, options);
}
} // namespace juce

+ 2
- 2
modules/juce_core/native/juce_linux_Network.cpp View File

@@ -607,9 +607,9 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
};
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost)
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, const DownloadTaskOptions& options)
{
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost);
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, options);
}
#endif


+ 18
- 16
modules/juce_core/native/juce_mac_Network.mm View File

@@ -412,10 +412,8 @@ struct BackgroundDownloadTask : public URL::DownloadTask
{
BackgroundDownloadTask (const URL& urlToUse,
const File& targetLocationToUse,
String extraHeadersToUse,
URL::DownloadTask::Listener* listenerToUse,
bool shouldUsePostRequest)
: listener (listenerToUse),
const URL::DownloadTaskOptions& options)
: listener (options.listener),
uniqueIdentifier (String (urlToUse.toString (true).hashCode64()) + String (Random().nextInt64()))
{
targetLocation = targetLocationToUse;
@@ -429,11 +427,11 @@ struct BackgroundDownloadTask : public URL::DownloadTask
auto nsUrl = [NSURL URLWithString: juceStringToNS (urlToUse.toString (true))];
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL: nsUrl];
if (shouldUsePostRequest)
if (options.usePost)
[request setHTTPMethod: @"POST"];
StringArray headerLines;
headerLines.addLines (extraHeadersToUse);
headerLines.addLines (options.extraHeaders);
headerLines.removeEmptyStrings (true);
for (int i = 0; i < headerLines.size(); ++i)
@@ -445,10 +443,14 @@ struct BackgroundDownloadTask : public URL::DownloadTask
[request addValue: juceStringToNS (value) forHTTPHeaderField: juceStringToNS (key)];
}
session =
[NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: juceStringToNS (uniqueIdentifier)]
delegate: delegate
delegateQueue: nullptr];
auto* configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: juceStringToNS (uniqueIdentifier)];
if (options.sharedContainer.isNotEmpty())
[configuration setSharedContainerIdentifier: juceStringToNS (options.sharedContainer)];
session = [NSURLSession sessionWithConfiguration: configuration
delegate: delegate
delegateQueue: nullptr];
if (session != nullptr)
downloadTask = [session downloadTaskWithRequest:request];
@@ -648,9 +650,9 @@ struct BackgroundDownloadTask : public URL::DownloadTask
HashMap<String, BackgroundDownloadTask*, DefaultHashFunctions, CriticalSection> BackgroundDownloadTask::activeSessions;
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool usePostRequest)
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, const DownloadTaskOptions& options)
{
std::unique_ptr<BackgroundDownloadTask> downloadTask (new BackgroundDownloadTask (*this, targetLocation, extraHeaders, listener, usePostRequest));
auto downloadTask = std::make_unique<BackgroundDownloadTask> (*this, targetLocation, options);
if (downloadTask->initOK() && downloadTask->connect())
return downloadTask;
@@ -663,9 +665,9 @@ void URL::DownloadTask::juce_iosURLSessionNotify (const String& identifier)
BackgroundDownloadTask::invokeNotify (identifier);
}
#else
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool usePost)
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, const DownloadTaskOptions& options)
{
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, usePost);
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, options);
}
#endif
@@ -929,9 +931,9 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (URLConnectionState)
};
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost)
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, const DownloadTaskOptions& options)
{
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost);
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, options);
}
JUCE_END_IGNORE_WARNINGS_GCC_LIKE


+ 2
- 2
modules/juce_core/native/juce_win32_Network.cpp View File

@@ -650,9 +650,9 @@ bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& targetEmailA
return mapiSendMail (0, 0, &message, MAPI_DIALOG | MAPI_LOGON_UI, 0) == SUCCESS_SUCCESS;
}
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost)
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, const DownloadTaskOptions& options)
{
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost);
return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, options);
}
} // namespace juce

+ 16
- 8
modules/juce_core/network/juce_URL.cpp View File

@@ -106,29 +106,26 @@ struct FallbackDownloadTask : public URL::DownloadTask,
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FallbackDownloadTask)
};
void URL::DownloadTask::Listener::progress (DownloadTask*, int64, int64) {}
URL::DownloadTask::Listener::~Listener() {}
void URL::DownloadTaskListener::progress (DownloadTask*, int64, int64) {}
//==============================================================================
std::unique_ptr<URL::DownloadTask> URL::DownloadTask::createFallbackDownloader (const URL& urlToUse,
const File& targetFileToUse,
const String& extraHeadersToUse,
Listener* listenerToUse,
bool usePostRequest)
const DownloadTaskOptions& options)
{
const size_t bufferSize = 0x8000;
targetFileToUse.deleteFile();
if (auto outputStream = targetFileToUse.createOutputStream (bufferSize))
{
auto stream = std::make_unique<WebInputStream> (urlToUse, usePostRequest);
stream->withExtraHeaders (extraHeadersToUse);
auto stream = std::make_unique<WebInputStream> (urlToUse, options.usePost);
stream->withExtraHeaders (options.extraHeaders);
if (stream->connect (nullptr))
return std::make_unique<FallbackDownloadTask> (std::move (outputStream),
bufferSize,
std::move (stream),
listenerToUse);
options.listener);
}
return nullptr;
@@ -1005,4 +1002,15 @@ std::unique_ptr<InputStream> URL::createInputStream (bool usePostCommand,
.withHttpRequestCmd (httpRequestCmd));
}
std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation,
String extraHeaders,
DownloadTask::Listener* listener,
bool usePostCommand)
{
auto options = DownloadTaskOptions().withExtraHeaders (std::move (extraHeaders))
.withListener (listener)
.withUsePost (usePostCommand);
return downloadToFile (targetLocation, std::move (options));
}
} // namespace juce

+ 68
- 20
modules/juce_core/network/juce_URL.h View File

@@ -428,29 +428,72 @@ public:
std::unique_ptr<OutputStream> createOutputStream() const;
//==============================================================================
/** Represents a download task.
class DownloadTask;
Returned by downloadToFile() to allow querying and controlling the download task.
/** Used to receive callbacks for download progress. */
struct JUCE_API DownloadTaskListener
{
virtual ~DownloadTaskListener() = default;
/** Called when the download has finished. Be aware that this callback may
come on an arbitrary thread.
*/
virtual void finished (DownloadTask* task, bool success) = 0;
/** Called periodically by the OS to indicate download progress.
Beware that this callback may come on an arbitrary thread.
*/
virtual void progress (DownloadTask* task, int64 bytesDownloaded, int64 totalLength);
};
/** Holds options that will can be specified when starting a new download
with downloadToFile().
*/
class JUCE_API DownloadTask
class DownloadTaskOptions
{
public:
/** Used to receive callbacks for download progress. */
struct JUCE_API Listener
{
virtual ~Listener();
String extraHeaders;
String sharedContainer;
DownloadTaskListener* listener = nullptr;
bool usePost = false;
/** Specifies headers to add to the request. */
auto withExtraHeaders (String value) const { return with (&DownloadTaskOptions::extraHeaders, std::move (value)); }
/** On iOS, specifies the container where the downloaded file will be stored.
If you initiate a download task from inside an app extension on iOS,
you must supply this option.
This is currently unused on other platforms.
*/
auto withSharedContainer (String value) const { return with (&DownloadTaskOptions::sharedContainer, std::move (value)); }
/** Called when the download has finished. Be aware that this callback may
come on an arbitrary thread.
*/
virtual void finished (URL::DownloadTask* task, bool success) = 0;
/** Specifies an observer for the download task. */
auto withListener (DownloadTaskListener* value) const { return with (&DownloadTaskOptions::listener, std::move (value)); }
/** Called periodically by the OS to indicate download progress.
/** Specifies whether a post command should be used. */
auto withUsePost (bool value) const { return with (&DownloadTaskOptions::usePost, value); }
Beware that this callback may come on an arbitrary thread.
*/
virtual void progress (URL::DownloadTask* task, int64 bytesDownloaded, int64 totalLength);
};
private:
template <typename Member, typename Value>
DownloadTaskOptions with (Member&& member, Value&& value) const
{
auto copy = *this;
copy.*member = std::forward<Value> (value);
return copy;
}
};
/** Represents a download task.
Returned by downloadToFile() to allow querying and controlling the download task.
*/
class JUCE_API DownloadTask
{
public:
using Listener = DownloadTaskListener;
/** Releases the resources of the download task, unregisters the listener
and cancels the download if necessary.
@@ -493,7 +536,7 @@ public:
private:
friend class URL;
static std::unique_ptr<DownloadTask> createFallbackDownloader (const URL&, const File&, const String&, Listener*, bool);
static std::unique_ptr<DownloadTask> createFallbackDownloader (const URL&, const File&, const DownloadTaskOptions&);
public:
#if JUCE_IOS
@@ -505,6 +548,13 @@ public:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadTask)
};
/** This function is replaced by a new overload accepting a DownloadTaskOptions argument. */
[[deprecated ("Use the overload with a DownloadTaskOptions argument instead")]]
std::unique_ptr<DownloadTask> downloadToFile (const File& targetLocation,
String extraHeaders = String(),
DownloadTaskListener* listener = nullptr,
bool usePostCommand = false);
/** Download the URL to a file.
This method attempts to download the URL to a given file location.
@@ -515,9 +565,7 @@ public:
network re-connections and continuing your download while your app is suspended.
*/
std::unique_ptr<DownloadTask> downloadToFile (const File& targetLocation,
String extraHeaders = String(),
DownloadTask::Listener* listener = nullptr,
bool usePostCommand = false);
const DownloadTaskOptions& options);
//==============================================================================
/** Tries to download the entire contents of this URL into a binary data block.


Loading…
Cancel
Save