diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj index bbd3512617..1b54babd11 100644 --- a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj @@ -77,6 +77,10 @@ isa = PBXBuildFile; fileRef = F90C8B0233A54F1445343F67; }; + 89AD16514B1F4133FFEA1DF9 = { + isa = PBXBuildFile; + fileRef = 96D99A08027CA35D6A4E5CFD; + }; 47ED2C78B05B8A6A00E36C46 = { isa = PBXBuildFile; fileRef = 685A261BE78585293F3EAD36; @@ -547,6 +551,13 @@ path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; }; + 96D99A08027CA35D6A4E5CFD = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = WebKit.framework; + path = System/Library/Frameworks/WebKit.framework; + sourceTree = SDKROOT; + }; 979F23EA9E5E76131299E886 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -866,6 +877,7 @@ 34F1320BC5C23702C08DF9F0, 23CD1A3F9067C3A0ECE7BB67, F90C8B0233A54F1445343F67, + 96D99A08027CA35D6A4E5CFD, ); name = Frameworks; sourceTree = ""; @@ -1236,6 +1248,7 @@ AC783ECD84496E0B77911EEE, B1981F62F6A91FD2F579A198, ECA44A41DA8A935178C1A1F4, + 89AD16514B1F4133FFEA1DF9, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj index 5d4d7ccbc1..7e554c352c 100644 --- a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj +++ b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj @@ -61,6 +61,10 @@ isa = PBXBuildFile; fileRef = 60795BF638A7024B62C0DF09; }; + 537E779F6008999191B2920A = { + isa = PBXBuildFile; + fileRef = 3058871156B921B9E5946C4F; + }; A783F6E198806332E7FB9744 = { isa = PBXBuildFile; fileRef = 8693552B5FA53C2003A66302; @@ -194,6 +198,13 @@ path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; }; + 3058871156B921B9E5946C4F = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = WebKit.framework; + path = System/Library/Frameworks/WebKit.framework; + sourceTree = SDKROOT; + }; 322D3066DCD98A8D0542236A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -491,6 +502,7 @@ 418405DCE48C1B4926143469, 0A58FDDF6FB9253F51939A52, 60795BF638A7024B62C0DF09, + 3058871156B921B9E5946C4F, ); name = Frameworks; sourceTree = ""; @@ -807,6 +819,7 @@ FA27764C3CB8C061B1B787CC, F8099BB77DC0D01DCCC6AFB9, AA0C9E035BB509F01A09310B, + 537E779F6008999191B2920A, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj index 46898eb32a..79a8102dda 100644 --- a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj @@ -73,6 +73,10 @@ isa = PBXBuildFile; fileRef = F9EDC54DFBCF3A63E0AA5D73; }; + 4DB15177DDC357F4503F88CF = { + isa = PBXBuildFile; + fileRef = B457EE687507BF1DEEA7581F; + }; 59F4F23BFFDAB414B4801F85 = { isa = PBXBuildFile; fileRef = 29E0972229FB44D969035B4E; @@ -530,6 +534,13 @@ path = ../../Source/JUCEAppIcon.png; sourceTree = "SOURCE_ROOT"; }; + B457EE687507BF1DEEA7581F = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = WebKit.framework; + path = System/Library/Frameworks/WebKit.framework; + sourceTree = SDKROOT; + }; B86B918291E1090C6A720971 = { isa = PBXFileReference; lastKnownFileType = file; @@ -763,6 +774,7 @@ D0026F0A29B486D87E92BB8B, 89309C0C5F3269BD06BE7F27, F9EDC54DFBCF3A63E0AA5D73, + B457EE687507BF1DEEA7581F, ); name = Frameworks; sourceTree = ""; @@ -1129,6 +1141,7 @@ 2AB9A26C9359C40CA0A937ED, A02C9F4C4B840C27B6CAFEBD, 50AFD116DCA6EC228EFB322D, + 4DB15177DDC357F4503F88CF, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj index d57d9a00ef..e9c6f690d3 100644 --- a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj +++ b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj @@ -65,6 +65,10 @@ isa = PBXBuildFile; fileRef = 379F77D23BFAE3795282CEB3; }; + 8ECB0767EE340DD83869E37D = { + isa = PBXBuildFile; + fileRef = EC794872987FEA2E129C589A; + }; 1282A62308CD1AC3F88A5D03 = { isa = PBXBuildFile; fileRef = 5273768FBB55D0DD57A5E70C; @@ -505,6 +509,13 @@ path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; }; + EC794872987FEA2E129C589A = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = WebKit.framework; + path = System/Library/Frameworks/WebKit.framework; + sourceTree = SDKROOT; + }; F7D557738137CA1A370BAA27 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -627,6 +638,7 @@ C821C5805007FFDC2636BBE6, 935CA85EF98714D3A17AE737, 379F77D23BFAE3795282CEB3, + EC794872987FEA2E129C589A, ); name = Frameworks; sourceTree = ""; @@ -955,6 +967,7 @@ A6AA70BD9364BB974CDEB337, EC14DA30C090DDC62084DB4C, F714F0C84F5945BF3539239E, + 8ECB0767EE340DD83869E37D, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/modules/juce_gui_extra/juce_gui_extra.cpp b/modules/juce_gui_extra/juce_gui_extra.cpp index d043e4542f..b4b02575e8 100644 --- a/modules/juce_gui_extra/juce_gui_extra.cpp +++ b/modules/juce_gui_extra/juce_gui_extra.cpp @@ -59,6 +59,8 @@ //============================================================================== #elif JUCE_IOS + #import + #if JUCE_PUSH_NOTIFICATIONS #if defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 #import diff --git a/modules/juce_gui_extra/juce_gui_extra.h b/modules/juce_gui_extra/juce_gui_extra.h index db475d98c0..143f2bf2a5 100644 --- a/modules/juce_gui_extra/juce_gui_extra.h +++ b/modules/juce_gui_extra/juce_gui_extra.h @@ -36,6 +36,7 @@ dependencies: juce_gui_basics OSXFrameworks: WebKit + iOSFrameworks: WebKit END_JUCE_MODULE_DECLARATION diff --git a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index 367c9002ec..632cd0543d 100644 --- a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -16,12 +16,254 @@ ============================================================================== */ -JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") +namespace juce +{ -#if JUCE_MAC +#if (defined (MAC_OS_X_VERSION_10_11) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11) \ + || (defined (__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0) -namespace juce + #define JUCE_USE_WKWEBVIEW 1 + + #if (defined (MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) + #define WKWEBVIEW_OPENPANEL_SUPPORTED 1 + #endif + +#endif + +NSMutableURLRequest* getRequestForURL (const String& url, const StringArray* headers, const MemoryBlock* postData) +{ + NSString* urlString = juceStringToNS (url); + + #if (JUCE_MAC && (defined (MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) \ + || (JUCE_IOS && (defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0)) + urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + #else + urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + #endif + + if (NSURL* nsURL = [NSURL URLWithString: urlString]) + { + NSMutableURLRequest* r + = [NSMutableURLRequest requestWithURL: nsURL + cachePolicy: NSURLRequestUseProtocolCachePolicy + timeoutInterval: 30.0]; + + if (postData != nullptr && postData->getSize() > 0) + { + [r setHTTPMethod: nsStringLiteral ("POST")]; + [r setHTTPBody: [NSData dataWithBytes: postData->getData() + length: postData->getSize()]]; + } + + if (headers != nullptr) + { + for (int i = 0; i < headers->size(); ++i) + { + auto headerName = (*headers)[i].upToFirstOccurrenceOf (":", false, false).trim(); + auto headerValue = (*headers)[i].fromFirstOccurrenceOf (":", false, false).trim(); + + [r setValue: juceStringToNS (headerValue) + forHTTPHeaderField: juceStringToNS (headerName)]; + } + } + + return r; + } + + return nullptr; +} + +#if JUCE_USE_WKWEBVIEW + +struct WebViewDelegateClass : public ObjCClass +{ + WebViewDelegateClass() : ObjCClass ("JUCEWebViewDelegate_") + { + addIvar ("owner"); + + addMethod (@selector (webView:decidePolicyForNavigationAction:decisionHandler:), decidePolicyForNavigationAction, "v@:@@@"); + addMethod (@selector (webView:didFinishNavigation:), didFinishNavigation, "v@:@@"); + addMethod (@selector (webView:didFailNavigation:withError:), didFailNavigation, "v@:@@@"); + addMethod (@selector (webView:didFailProvisionalNavigation:withError:), didFailProvisionalNavigation, "v@:@@@"); + + addMethod (@selector (webView:webViewDidClose:), webViewDidClose, "v@:@"); + addMethod (@selector (webView:createWebViewWithConfiguration:forNavigationAction: + windowFeatures:), createWebView, "@@:@@@@"); + + #if WKWEBVIEW_OPENPANEL_SUPPORTED + addMethod (@selector (webView:runOpenPanelWithParameters: + initiatedByFrame:completionHandler:), runOpenPanel, "v@:@@@@"); + #endif + + registerClass(); + } + + static void setOwner (id self, WebBrowserComponent* owner) { object_setInstanceVariable (self, "owner", owner); } + static WebBrowserComponent* getOwner (id self) { return getIvar (self, "owner"); } + +private: + static void decidePolicyForNavigationAction (id self, SEL, WKWebView*, WKNavigationAction* navigationAction, + void (^decisionHandler)(WKNavigationActionPolicy)) + { + if (getOwner (self)->pageAboutToLoad (nsStringToJuce ([[[navigationAction request] URL] absoluteString]))) + decisionHandler (WKNavigationActionPolicyAllow); + else + decisionHandler (WKNavigationActionPolicyCancel); + } + + static void didFinishNavigation (id self, SEL, WKWebView* webview, WKNavigation*) + { + getOwner (self)->pageFinishedLoading (nsStringToJuce ([[webview URL] absoluteString])); + } + + static void displayError (WebBrowserComponent* owner, NSError* error) + { + if ([error code] != NSURLErrorCancelled) + { + auto errorString = nsStringToJuce ([error localizedDescription]); + bool proceedToErrorPage = owner->pageLoadHadNetworkError (errorString); + + // WKWebView doesn't have an internal error page, so make a really simple one ourselves + if (proceedToErrorPage) + owner->goToURL ("data:text/plain;charset=UTF-8," + errorString); + } + } + + static void didFailNavigation (id self, SEL, WKWebView*, WKNavigation*, NSError* error) + { + displayError (getOwner (self), error); + } + + static void didFailProvisionalNavigation (id self, SEL, WKWebView*, WKNavigation*, NSError* error) + { + displayError (getOwner (self), error); + } + + static void webViewDidClose (id self, SEL, WKWebView*) + { + getOwner (self)->windowCloseRequest(); + } + + static WKWebView* createWebView (id self, SEL, WKWebView*, WKWebViewConfiguration*, + WKNavigationAction* navigationAction, WKWindowFeatures*) + { + getOwner (self)->newWindowAttemptingToLoad (nsStringToJuce ([[[navigationAction request] URL] absoluteString])); + return nil; + } + + #if WKWEBVIEW_OPENPANEL_SUPPORTED + static void runOpenPanel (id, SEL, WKWebView*, WKOpenPanelParameters* parameters, WKFrameInfo*, + void (^completionHandler)(NSArray*)) + { + #if JUCE_MODAL_LOOPS_PERMITTED + FileChooser chooser (TRANS("Select the file you want to upload..."), + File::getSpecialLocation (File::userHomeDirectory), "*"); + + auto flags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles + | ([parameters allowsMultipleSelection] ? FileBrowserComponent::canSelectMultipleItems : 0); + + #if (defined (MAC_OS_X_VERSION_10_14) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_14) + if ([parameters allowsDirectories]) + flags |= FileBrowserComponent::canSelectDirectories; + #endif + + if (chooser.showDialog (flags, nullptr)) + { + auto results = chooser.getResults(); + auto urls = [NSMutableArray arrayWithCapacity: (NSUInteger) results.size()]; + + for (auto& f : results) + [urls addObject: [NSURL fileURLWithPath: juceStringToNS (f.getFullPathName())]]; + + completionHandler (urls); + } + else + { + completionHandler (nil); + } + #else + ignoreUnused (parameters, completionHandler); + jassertfalse; // Can't use this without modal loops being enabled! + #endif + } + #endif +}; + +//============================================================================== +class WebBrowserComponent::Pimpl + #if JUCE_MAC + : public NSViewComponent + #else + : public UIViewComponent + #endif { +public: + Pimpl (WebBrowserComponent* owner) + { + ignoreUnused (owner); + + WKWebViewConfiguration* config = [[WKWebViewConfiguration alloc] init]; + + #if JUCE_MAC + auto frame = NSMakeRect (0, 0, 100.0f, 100.0f); + #else + auto frame = CGRectMake (0, 0, 100.0f, 100.0f); + #endif + + webView = [[WKWebView alloc] initWithFrame: frame + configuration: config]; + + static WebViewDelegateClass cls; + webViewDelegate = [cls.createInstance() init]; + WebViewDelegateClass::setOwner (webViewDelegate, owner); + + [webView setNavigationDelegate: webViewDelegate]; + [webView setUIDelegate: webViewDelegate]; + + setView (webView); + } + + ~Pimpl() + { + [webView setNavigationDelegate: nil]; + [webView setUIDelegate: nil]; + + [webViewDelegate release]; + + setView (nil); + } + + void goToURL (const String& url, + const StringArray* headers, + const MemoryBlock* postData) + { + stop(); + + if (url.trimStart().startsWithIgnoreCase ("javascript:")) + { + [webView evaluateJavaScript: juceStringToNS (url.fromFirstOccurrenceOf (":", false, false)) + completionHandler: nil]; + } + else if (NSMutableURLRequest* request = getRequestForURL (url, headers, postData)) + { + [webView loadRequest: request]; + } + } + + void goBack() { [webView goBack]; } + void goForward() { [webView goForward]; } + + void stop() { [webView stopLoading]; } + void refresh() { [webView reload]; } + +private: + WKWebView* webView = nil; + id webViewDelegate; +}; + +#else + +#if JUCE_MAC struct WebViewKeyEquivalentResponder : public ObjCClass { @@ -36,11 +278,7 @@ private: { NSResponder* first = [[self window] firstResponder]; - #if (defined (MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) - if (([event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagCommand) - #else if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask) - #endif { if ([[event charactersIgnoringModifiers] isEqualToString:@"x"]) return [NSApp sendAction:@selector(cut:) to:first from:self]; if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) return [NSApp sendAction:@selector(copy:) to:first from:self]; @@ -148,62 +386,40 @@ private: #else -//============================================================================== -@interface WebViewTapDetector : NSObject -{ -} - -- (BOOL) gestureRecognizer: (UIGestureRecognizer*) gestureRecognizer - shouldRecognizeSimultaneouslyWithGestureRecognizer: (UIGestureRecognizer*) otherGestureRecognizer; -@end - -@implementation WebViewTapDetector - -- (BOOL) gestureRecognizer: (UIGestureRecognizer*) gestureRecognizer - shouldRecognizeSimultaneouslyWithGestureRecognizer: (UIGestureRecognizer*) otherGestureRecognizer +struct WebViewDelegateClass : public ObjCClass { - juce::ignoreUnused (gestureRecognizer, otherGestureRecognizer); - return YES; -} - -@end + WebViewDelegateClass() : ObjCClass ("JUCEWebViewDelegate_") + { + addIvar ("owner"); -//============================================================================== -@interface WebViewURLChangeDetector : NSObject -{ - juce::WebBrowserComponent* ownerComponent; -} + addMethod (@selector (gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:), + shouldRecognizeSimultaneouslyWithGestureRecognizer, "c@:@@"); -- (WebViewURLChangeDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComponent; -- (BOOL) webView: (UIWebView*) webView shouldStartLoadWithRequest: (NSURLRequest*) request - navigationType: (UIWebViewNavigationType) navigationType; -- (void) webViewDidFinishLoad: (UIWebView*) webView; -@end + addMethod (@selector (webView:shouldStartLoadWithRequest:navigationType:), shouldStartLoadWithRequest, "c@:@@@"); + addMethod (@selector (webViewDidFinishLoad:), webViewDidFinishLoad, "v@:@"); -@implementation WebViewURLChangeDetector + registerClass(); + } -- (WebViewURLChangeDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComp -{ - [super init]; - ownerComponent = ownerComp; - return self; -} + static void setOwner (id self, WebBrowserComponent* owner) { object_setInstanceVariable (self, "owner", owner); } + static WebBrowserComponent* getOwner (id self) { return getIvar (self, "owner"); } -- (BOOL) webView: (UIWebView*) webView shouldStartLoadWithRequest: (NSURLRequest*) request - navigationType: (UIWebViewNavigationType) navigationType -{ - juce::ignoreUnused (webView, navigationType); - return ownerComponent->pageAboutToLoad (juce::nsStringToJuce (request.URL.absoluteString)); -} +private: + static BOOL shouldRecognizeSimultaneouslyWithGestureRecognizer (id, SEL, UIGestureRecognizer*, UIGestureRecognizer*) + { + return YES; + } -- (void) webViewDidFinishLoad: (UIWebView*) webView -{ - ownerComponent->pageFinishedLoading (juce::nsStringToJuce (webView.request.URL.absoluteString)); -} -@end + static BOOL shouldStartLoadWithRequest (id self, SEL, UIWebView*, NSURLRequest* request, UIWebViewNavigationType) + { + return getOwner (self)->pageAboutToLoad (nsStringToJuce ([[request URL] absoluteString])); + } -namespace juce -{ + static void webViewDidFinishLoad (id self, SEL, UIWebView* webView) + { + getOwner (self)->pageFinishedLoading (nsStringToJuce ([[[webView request] URL] absoluteString])); + } +}; #endif @@ -225,38 +441,38 @@ public: webView = [webView initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) frameName: nsEmptyString() groupName: nsEmptyString()]; - setView (webView); static DownloadClickDetectorClass cls; clickListener = [cls.createInstance() init]; DownloadClickDetectorClass::setOwner (clickListener, owner); - [webView setPolicyDelegate: clickListener]; + + [webView setPolicyDelegate: clickListener]; [webView setFrameLoadDelegate: clickListener]; - [webView setUIDelegate: clickListener]; + [webView setUIDelegate: clickListener]; #else webView = [[UIWebView alloc] initWithFrame: CGRectMake (0, 0, 1.0f, 1.0f)]; - setView (webView); - tapDetector = [[WebViewTapDetector alloc] init]; - urlDetector = [[WebViewURLChangeDetector alloc] initWithWebBrowserOwner: owner]; - gestureRecogniser = nil; - webView.delegate = urlDetector; + static WebViewDelegateClass cls; + webViewDelegate = [cls.createInstance() init]; + WebViewDelegateClass::setOwner (webViewDelegate, owner); + + [webView setDelegate: webViewDelegate]; #endif + + setView (webView); } ~Pimpl() { #if JUCE_MAC - [webView setPolicyDelegate: nil]; + [webView setPolicyDelegate: nil]; [webView setFrameLoadDelegate: nil]; - [webView setUIDelegate: nil]; + [webView setUIDelegate: nil]; + [clickListener release]; #else - webView.delegate = nil; - [webView removeGestureRecognizer: gestureRecogniser]; - [gestureRecogniser release]; - [tapDetector release]; - [urlDetector release]; + [webView setDelegate: nil]; + [webViewDelegate release]; #endif setView (nil); @@ -273,52 +489,17 @@ public: [webView stringByEvaluatingJavaScriptFromString: juceStringToNS (url.fromFirstOccurrenceOf (":", false, false))]; } - else + else if (NSMutableURLRequest* request = getRequestForURL (url, headers, postData)) { - NSString* urlString = juceStringToNS (url); - - #if (JUCE_MAC && (defined (MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) || (JUCE_IOS && (defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0)) - urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + #if JUCE_MAC + [[webView mainFrame] loadRequest: request]; #else - urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + [webView loadRequest: request]; #endif - if (NSURL* nsURL = [NSURL URLWithString: urlString]) - { - NSMutableURLRequest* r - = [NSMutableURLRequest requestWithURL: nsURL - cachePolicy: NSURLRequestUseProtocolCachePolicy - timeoutInterval: 30.0]; - - if (postData != nullptr && postData->getSize() > 0) - { - [r setHTTPMethod: nsStringLiteral ("POST")]; - [r setHTTPBody: [NSData dataWithBytes: postData->getData() - length: postData->getSize()]]; - } - - if (headers != nullptr) - { - for (int i = 0; i < headers->size(); ++i) - { - auto headerName = (*headers)[i].upToFirstOccurrenceOf (":", false, false).trim(); - auto headerValue = (*headers)[i].fromFirstOccurrenceOf (":", false, false).trim(); - - [r setValue: juceStringToNS (headerValue) - forHTTPHeaderField: juceStringToNS (headerName)]; - } - } - - #if JUCE_MAC - [[webView mainFrame] loadRequest: r]; - #else - [webView loadRequest: r]; - #endif - - #if JUCE_IOS - [webView setScalesPageToFit:YES]; - #endif - } + #if JUCE_IOS + [webView setScalesPageToFit: YES]; + #endif } } @@ -343,17 +524,15 @@ public: private: #if JUCE_MAC - WebView* webView; + WebView* webView = nil; id clickListener; #else - UIWebView* webView; - WebViewTapDetector* tapDetector; - WebViewURLChangeDetector* urlDetector; - UITapGestureRecognizer* gestureRecogniser; + UIWebView* webView = nil; + id webViewDelegate; #endif }; -JUCE_END_IGNORE_WARNINGS_GCC_LIKE +#endif //============================================================================== WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden)