From 8b694526434133cf17eec6806020b1741efdcdf6 Mon Sep 17 00:00:00 2001 From: Caleb Clarke Date: Fri, 14 Aug 2020 20:16:54 -0700 Subject: [PATCH] feat(ios): Add iOS contentMode property (#1538 by @TheAlmightyBob) This allows overriding iPadOS 13's desktop-class browsing to load mobile content instead of desktop content. Co-authored-by: Jamon Holmgren --- apple/RNCWebView.h | 4 ++++ apple/RNCWebView.m | 8 ++++++++ apple/RNCWebViewManager.m | 14 ++++++++++++++ docs/Reference.md | 19 +++++++++++++++++++ src/WebViewTypes.ts | 15 +++++++++++++++ 5 files changed, 60 insertions(+) diff --git a/apple/RNCWebView.h b/apple/RNCWebView.h index c55950f..a0f8549 100644 --- a/apple/RNCWebView.h +++ b/apple/RNCWebView.h @@ -63,6 +63,10 @@ @property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch; @property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL; +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ +@property (nonatomic, assign) WKContentMode contentMode; +#endif + + (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential; + (void)setCustomCertificatesForHost:(nullable NSDictionary *)certificates; - (void)postMessage:(NSString *_Nullable)message; diff --git a/apple/RNCWebView.m b/apple/RNCWebView.m index eddbf21..0f32e94 100644 --- a/apple/RNCWebView.m +++ b/apple/RNCWebView.m @@ -226,6 +226,14 @@ static NSDictionary* customCertificatesForHost; } wkWebViewConfig.userContentController = [WKUserContentController new]; +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ + if (@available(iOS 13.0, *)) { + WKWebpagePreferences *pagePrefs = [[WKWebpagePreferences alloc]init]; + pagePrefs.preferredContentMode = _contentMode; + wkWebViewConfig.defaultWebpagePreferences = pagePrefs; + } +#endif + // Shim the HTML5 history API: [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self] name:HistoryShimName]; diff --git a/apple/RNCWebViewManager.m b/apple/RNCWebViewManager.m index 23ab93b..35c55a7 100644 --- a/apple/RNCWebViewManager.m +++ b/apple/RNCWebViewManager.m @@ -14,6 +14,16 @@ @interface RNCWebViewManager () @end +@implementation RCTConvert (WKWebView) +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ +RCT_ENUM_CONVERTER(WKContentMode, (@{ + @"recommended": @(WKContentModeRecommended), + @"mobile": @(WKContentModeMobile), + @"desktop": @(WKContentModeDesktop), +}), WKContentModeRecommended, integerValue) +#endif +@end + @implementation RNCWebViewManager { NSConditionLock *_shouldStartLoadLock; @@ -70,6 +80,10 @@ RCT_EXPORT_VIEW_PROPERTY(allowingReadAccessToURL, NSString) RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior) #endif +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ +RCT_EXPORT_VIEW_PROPERTY(contentMode, WKContentMode) +#endif + /** * Expose methods to enable messaging the webview. */ diff --git a/docs/Reference.md b/docs/Reference.md index 3b53bc5..22faff2 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -45,6 +45,7 @@ This document lays out the current public properties and methods for the React N - [`overScrollMode`](Reference.md#overscrollmode) - [`contentInset`](Reference.md#contentinset) - [`contentInsetAdjustmentBehavior`](Reference.md#contentInsetAdjustmentBehavior) +- [`contentMode`](Reference.md#contentMode) - [`dataDetectorTypes`](Reference.md#datadetectortypes) - [`scrollEnabled`](Reference.md#scrollenabled) - [`directionalLockEnabled`](Reference.md#directionalLockEnabled) @@ -917,6 +918,24 @@ Possible values: --- +### `contentMode`[⬆](#props-index) + +Controls the type of content to load. Available on iOS 13 and later. Defaults to `recommended`, which loads mobile content on iPhone & iPad Mini but desktop content on larger iPads. + +See [Introducing Desktop-class Browsing on iPad](https://developer.apple.com/videos/play/wwdc2019/203/) for more. + +Possible values: + +- `recommended` +- `mobile` +- `desktop` + +| Type | Required | Platform | +| ------ | -------- | -------- | +| string | No | iOS | + +--- + ### `dataDetectorTypes`[⬆](#props-index) Determines the types of data converted to clickable URLs in the web view's content. By default only phone numbers are detected. diff --git a/src/WebViewTypes.ts b/src/WebViewTypes.ts index 6252dd6..0a3c77b 100644 --- a/src/WebViewTypes.ts +++ b/src/WebViewTypes.ts @@ -299,6 +299,8 @@ export enum ContentInsetAdjustmentBehavior { always = 'always' }; +export declare type ContentMode = 'recommended' | 'mobile' | 'desktop'; + export interface IOSNativeWebViewProps extends CommonNativeWebViewProps { allowingReadAccessToURL?: string; allowsBackForwardNavigationGestures?: boolean; @@ -308,6 +310,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps { bounces?: boolean; contentInset?: ContentInsetProp; contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior; + contentMode?: ContentMode; readonly dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[]; decelerationRate?: number; directionalLockEnabled?: boolean; @@ -405,6 +408,18 @@ export interface IOSWebViewProps extends WebViewSharedProps { */ contentInset?: ContentInsetProp; + /** + * Defaults to `recommended`, which loads mobile content on iPhone + * and iPad Mini but desktop content on other iPads. + * + * Possible values are: + * - `'recommended'` + * - `'mobile'` + * - `'desktop'` + * @platform ios + */ + contentMode?: ContentMode; + /** * Determines the types of data converted to clickable URLs in the web view's content. * By default only phone numbers are detected.