| @@ -198,7 +198,7 @@ URL::URL (URL&& other) | |||||
| parameterValues (static_cast<StringArray&&> (other.parameterValues)), | parameterValues (static_cast<StringArray&&> (other.parameterValues)), | ||||
| filesToUpload (static_cast<ReferenceCountedArray<Upload>&&> (other.filesToUpload)) | filesToUpload (static_cast<ReferenceCountedArray<Upload>&&> (other.filesToUpload)) | ||||
| #if JUCE_IOS | #if JUCE_IOS | ||||
| , bookmark (other.bookmark) | |||||
| , bookmark (static_cast<Bookmark::Ptr&&> (other.bookmark)) | |||||
| #endif | #endif | ||||
| { | { | ||||
| } | } | ||||
| @@ -210,8 +210,8 @@ URL& URL::operator= (URL&& other) | |||||
| parameterNames = static_cast<StringArray&&> (other.parameterNames); | parameterNames = static_cast<StringArray&&> (other.parameterNames); | ||||
| parameterValues = static_cast<StringArray&&> (other.parameterValues); | parameterValues = static_cast<StringArray&&> (other.parameterValues); | ||||
| filesToUpload = static_cast<ReferenceCountedArray<Upload>&&> (other.filesToUpload); | filesToUpload = static_cast<ReferenceCountedArray<Upload>&&> (other.filesToUpload); | ||||
| #if JUCE_IOS | |||||
| bookmark = other.bookmark; | |||||
| #if JUCE_IOS | |||||
| bookmark = static_cast<Bookmark::Ptr&&> (other.bookmark); | |||||
| #endif | #endif | ||||
| return *this; | return *this; | ||||
| @@ -501,14 +501,27 @@ bool URL::isProbablyAnEmailAddress (const String& possibleEmailAddress) | |||||
| } | } | ||||
| #if JUCE_IOS | #if JUCE_IOS | ||||
| URL::Bookmark::Bookmark (void* bookmarkToUse) | |||||
| : data (bookmarkToUse) | |||||
| { | |||||
| } | |||||
| URL::Bookmark::~Bookmark() | |||||
| { | |||||
| [(NSData*) data release]; | |||||
| } | |||||
| void setURLBookmark (URL& u, void* bookmark) | void setURLBookmark (URL& u, void* bookmark) | ||||
| { | { | ||||
| u.bookmark = bookmark; | |||||
| u.bookmark = new URL::Bookmark (bookmark); | |||||
| } | } | ||||
| void* getURLBookmark (URL& u) | void* getURLBookmark (URL& u) | ||||
| { | { | ||||
| return u.bookmark; | |||||
| if (u.bookmark.get() == nullptr) | |||||
| return nullptr; | |||||
| return u.bookmark.get()->data; | |||||
| } | } | ||||
| template <typename Stream> struct iOSFileStreamWrapperFlush { static void flush (Stream*) {} }; | template <typename Stream> struct iOSFileStreamWrapperFlush { static void flush (Stream*) {} }; | ||||
| @@ -529,7 +529,17 @@ private: | |||||
| ReferenceCountedArray<Upload> filesToUpload; | ReferenceCountedArray<Upload> filesToUpload; | ||||
| #if JUCE_IOS | #if JUCE_IOS | ||||
| void* bookmark; | |||||
| struct Bookmark : public ReferenceCountedObject | |||||
| { | |||||
| using Ptr = ReferenceCountedObjectPtr<Bookmark>; | |||||
| Bookmark (void*); | |||||
| ~Bookmark(); | |||||
| void* data; | |||||
| }; | |||||
| Bookmark::Ptr bookmark; | |||||
| friend void setURLBookmark (URL&, void*); | friend void setURLBookmark (URL&, void*); | ||||
| friend void* getURLBookmark (URL&); | friend void* getURLBookmark (URL&); | ||||
| @@ -237,9 +237,14 @@ public: | |||||
| may return a URL to a remote document. If a local file is chosen then you can | may return a URL to a remote document. If a local file is chosen then you can | ||||
| convert this file to a JUCE File class via the URL::getLocalFile method. | convert this file to a JUCE File class via the URL::getLocalFile method. | ||||
| Note: on iOS it is best to dispose any copies of returned URL as soon as | |||||
| you finish dealing with the file. This is because URL might be security | |||||
| scoped and a system allows only for a limited number of such URLs. | |||||
| Note: on iOS you must use the returned URL object directly (you are also | |||||
| allowed to copy- or move-construct another URL from the returned URL), rather | |||||
| than just storing the path as a String and then creating a new URL from that | |||||
| String. This is because the returned URL contains internally a security | |||||
| bookmark that is required to access the files pointed by it. Then, once you stop | |||||
| dealing with the file pointed by the URL, you should dispose that URL object, | |||||
| so that the security bookmark can be released by the system (only a limited | |||||
| number of such URLs is allowed). | |||||
| @see getResult, URL::getLocalFile | @see getResult, URL::getLocalFile | ||||
| */ | */ | ||||
| @@ -255,9 +260,14 @@ public: | |||||
| This array may be empty if no files were chosen, or can contain multiple entries | This array may be empty if no files were chosen, or can contain multiple entries | ||||
| if multiple files were chosen. | if multiple files were chosen. | ||||
| Note: on iOS it is best to dispose any copies of returned URLs as soon as | |||||
| you finish dealing with the file. This is because URLs might be security | |||||
| scoped and a system allows only for a limited number of such URLs. | |||||
| Note: on iOS you must use the returned URL object directly (you are also | |||||
| allowed to copy- or move-construct another URL from the returned URL), rather | |||||
| than just storing the path as a String and then creating a new URL from that | |||||
| String. This is because the returned URL contains internally a security | |||||
| bookmark that is required to access the files pointed by it. Then, once you stop | |||||
| dealing with the file pointed by the URL, you should dispose that URL object, | |||||
| so that the security bookmark can be released by the system (only a limited | |||||
| number of such URLs is allowed). | |||||
| @see getResults, URL::getLocalFile | @see getResults, URL::getLocalFile | ||||
| */ | */ | ||||
| @@ -217,6 +217,8 @@ private: | |||||
| relativeToURL: nil | relativeToURL: nil | ||||
| error: &error]; | error: &error]; | ||||
| [bookmark retain]; | |||||
| [url stopAccessingSecurityScopedResource]; | [url stopAccessingSecurityScopedResource]; | ||||
| URL juceUrl (nsStringToJuce ([url absoluteString])); | URL juceUrl (nsStringToJuce ([url absoluteString])); | ||||