Skip to content

Commit b9e345a

Browse files
feat(ios): add webContentsDebuggingEnabled configuration (#6500)
Co-authored-by: jcesarmobile <jcesarmobile@gmail.com>
1 parent 6028ff4 commit b9e345a

11 files changed

+67
-0
lines changed

cli/src/declarations.ts

+10
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,16 @@ export interface CapacitorConfig {
436436
* @default true
437437
*/
438438
handleApplicationNotifications?: boolean;
439+
440+
/**
441+
* Using Xcode 14.3, on iOS 16.4 and greater, enable debuggable web content for release builds.
442+
*
443+
* If not set, it's `true` for development builds.
444+
*
445+
* @since 4.8.0
446+
* @default false
447+
*/
448+
webContentsDebuggingEnabled?: boolean;
439449
};
440450

441451
server?: {

ios/Capacitor/Capacitor.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
2F81F5CA26FB7CB400DD35BE /* CAPBridgeViewController+CDVScreenOrientationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F81F5C826FB7CB400DD35BE /* CAPBridgeViewController+CDVScreenOrientationDelegate.m */; };
1414
373A69C1255C9360000A6F44 /* NotificationHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A69C0255C9360000A6F44 /* NotificationHandlerProtocol.swift */; };
1515
373A69F2255C95D0000A6F44 /* NotificationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A69F1255C95D0000A6F44 /* NotificationRouter.swift */; };
16+
4D0D590F29E86FAB008A6833 /* WKWebView+Capacitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D0D590D29E86FAB008A6833 /* WKWebView+Capacitor.h */; settings = {ATTRIBUTES = (Public, ); }; };
1617
501CBAA71FC0A723009B0D4D /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 501CBAA61FC0A723009B0D4D /* WebKit.framework */; };
1718
50503EE91FC08595003606DC /* Capacitor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50503EDF1FC08594003606DC /* Capacitor.framework */; };
1819
50503EEE1FC08595003606DC /* CapacitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50503EED1FC08595003606DC /* CapacitorTests.swift */; };
@@ -142,6 +143,7 @@
142143
2F81F5C826FB7CB400DD35BE /* CAPBridgeViewController+CDVScreenOrientationDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CAPBridgeViewController+CDVScreenOrientationDelegate.m"; sourceTree = "<group>"; };
143144
373A69C0255C9360000A6F44 /* NotificationHandlerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandlerProtocol.swift; sourceTree = "<group>"; };
144145
373A69F1255C95D0000A6F44 /* NotificationRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationRouter.swift; sourceTree = "<group>"; };
146+
4D0D590D29E86FAB008A6833 /* WKWebView+Capacitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WKWebView+Capacitor.h"; sourceTree = "<group>"; };
145147
501CBAA61FC0A723009B0D4D /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
146148
50503EDF1FC08594003606DC /* Capacitor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Capacitor.framework; sourceTree = BUILT_PRODUCTS_DIR; };
147149
50503EE81FC08595003606DC /* CapacitorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CapacitorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -356,6 +358,7 @@
356358
62959B112524DA7700A3D7F1 /* Data+Capacitor.swift */,
357359
62FABD1925AE5C01007B3814 /* Array+Capacitor.swift */,
358360
62D43AEF2581817500673C24 /* WKWebView+Capacitor.swift */,
361+
4D0D590D29E86FAB008A6833 /* WKWebView+Capacitor.h */,
359362
62D43B642582A13D00673C24 /* WKWebView+Capacitor.m */,
360363
2F81F5C726FB7CB400DD35BE /* CAPBridgeViewController+CDVScreenOrientationDelegate.h */,
361364
2F81F5C826FB7CB400DD35BE /* CAPBridgeViewController+CDVScreenOrientationDelegate.m */,
@@ -438,6 +441,7 @@
438441
buildActionMask = 2147483647;
439442
files = (
440443
62959B412524DA7800A3D7F1 /* Capacitor.h in Headers */,
444+
4D0D590F29E86FAB008A6833 /* WKWebView+Capacitor.h in Headers */,
441445
62959B452524DA7800A3D7F1 /* CAPPlugin.h in Headers */,
442446
62959B162524DA7800A3D7F1 /* CAPPluginCall.h in Headers */,
443447
62959B3B2524DA7800A3D7F1 /* CAPPluginMethod.h in Headers */,

ios/Capacitor/Capacitor/CAPInstanceConfiguration.h

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ NS_SWIFT_NAME(InstanceConfiguration)
1919
@property (nonatomic, readonly) BOOL scrollingEnabled;
2020
@property (nonatomic, readonly) BOOL allowLinkPreviews;
2121
@property (nonatomic, readonly) BOOL handleApplicationNotifications;
22+
@property (nonatomic, readonly) BOOL isWebDebuggable;
2223
@property (nonatomic, readonly) BOOL cordovaDeployDisabled;
2324
@property (nonatomic, readonly) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior;
2425
@property (nonatomic, readonly, nonnull) NSURL *appLocation;

ios/Capacitor/Capacitor/CAPInstanceConfiguration.m

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ - (instancetype)initWithDescriptor:(CAPInstanceDescriptor *)descriptor isDebug:(
3737
_limitsNavigationsToAppBoundDomains = descriptor.limitsNavigationsToAppBoundDomains;
3838
_preferredContentMode = descriptor.preferredContentMode;
3939
_pluginConfigurations = descriptor.pluginConfigurations;
40+
_isWebDebuggable = descriptor.isWebDebuggable;
4041
_legacyConfig = descriptor.legacyConfig;
4142
// construct the necessary URLs
4243
_localURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@://%@", descriptor.urlScheme, descriptor.urlHostname]];
@@ -67,6 +68,7 @@ - (instancetype)initWithConfiguration:(CAPInstanceConfiguration*)configuration a
6768
_scrollingEnabled = configuration.scrollingEnabled;
6869
_allowLinkPreviews = configuration.allowLinkPreviews;
6970
_handleApplicationNotifications = configuration.handleApplicationNotifications;
71+
_isWebDebuggable = configuration.isWebDebuggable;
7072
_cordovaDeployDisabled = configuration.cordovaDeployDisabled;
7173
_contentInsetAdjustmentBehavior = configuration.contentInsetAdjustmentBehavior;
7274
// we don't care about internal usage of deprecated APIs and the framework should build cleanly

ios/Capacitor/Capacitor/CAPInstanceDescriptor.h

+5
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ NS_SWIFT_NAME(InstanceDescriptor)
9393
@discussion Defaults to @c true. Required to be @c true for notification plugins to work correctly. Set to @c false if your application will handle notifications independently.
9494
*/
9595
@property (nonatomic, assign) BOOL handleApplicationNotifications;
96+
/**
97+
@brief Enables web debugging by setting isInspectable of @c WKWebView to @c true on iOS 16.4 and greater
98+
@discussion Defaults to true in debug mode and false in production
99+
*/
100+
@property (nonatomic, assign) BOOL isWebDebuggable;
96101
/**
97102
@brief How the web view will inset its content
98103
@discussion Set by @c ios.contentInset in the configuration file. Corresponds to @c contentInsetAdjustmentBehavior on WKWebView.

ios/Capacitor/Capacitor/CAPInstanceDescriptor.m

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ - (void)_setDefaultsWithAppLocation:(NSURL*)location {
3939
_scrollingEnabled = YES;
4040
_allowLinkPreviews = YES;
4141
_handleApplicationNotifications = YES;
42+
_isWebDebuggable = NO;
4243
_contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
4344
_appLocation = location;
4445
_limitsNavigationsToAppBoundDomains = FALSE;

ios/Capacitor/Capacitor/CAPInstanceDescriptor.swift

+7
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ internal extension InstanceDescriptor {
134134
if let handleNotifications = config[keyPath: "ios.handleApplicationNotifications"] as? Bool {
135135
handleApplicationNotifications = handleNotifications
136136
}
137+
if let webContentsDebuggingEnabled = config[keyPath: "ios.webContentsDebuggingEnabled"] as? Bool {
138+
isWebDebuggable = webContentsDebuggingEnabled
139+
} else {
140+
#if DEBUG
141+
isWebDebuggable = true
142+
#endif
143+
}
137144
}
138145
}
139146
// swiftlint:enable cyclomatic_complexity

ios/Capacitor/Capacitor/Capacitor.h

+2
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ FOUNDATION_EXPORT const unsigned char CapacitorVersionString[];
1212
#import <Capacitor/CAPPluginMethod.h>
1313
#import <Capacitor/CAPInstanceDescriptor.h>
1414
#import <Capacitor/CAPInstanceConfiguration.h>
15+
#import <Capacitor/WKWebView+Capacitor.h>
16+

ios/Capacitor/Capacitor/CapacitorBridge.swift

+11
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ internal class CapacitorBridge: NSObject, CAPBridgeProtocol {
209209
observers.append(NotificationCenter.default.addObserver(forName: type(of: self).tmpVCAppeared.name, object: .none, queue: .none) { [weak self] _ in
210210
self?.tmpWindow = nil
211211
})
212+
213+
self.setupWebDebugging(configuration: configuration)
212214
}
213215

214216
deinit {
@@ -436,6 +438,15 @@ internal class CapacitorBridge: NSObject, CAPBridgeProtocol {
436438
return "\(type(of: self).capacitorSite)docs/\(url)"
437439
}
438440

441+
private func setupWebDebugging(configuration: InstanceConfiguration) {
442+
let isWebDebuggable = configuration.isWebDebuggable
443+
if isWebDebuggable, #unavailable(iOS 16.4) {
444+
CAPLog.print("⚡️ Warning: isWebDebuggable only functions as intended on iOS 16.4 and above.")
445+
}
446+
447+
self.webView?.setInspectableIfRequired(isWebDebuggable)
448+
}
449+
439450
/**
440451
Handle a call from JavaScript. First, find the corresponding plugin, construct a selector,
441452
and perform that selector on the plugin instance.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@import UIKit;
2+
@import WebKit;
3+
4+
#ifndef WKWebView_Capacitor_h
5+
#define WKWebView_Capacitor_h
6+
7+
@interface WKWebView (CapacitorInspectablity)
8+
- (void)setInspectableIfRequired: (BOOL)shouldInspect;
9+
@end
10+
11+
#endif /* WKWebView_Capacitor_h */

ios/Capacitor/Capacitor/WKWebView+Capacitor.m

+13
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,16 @@ + (void)load {
1313
[self _swizzleKeyboardMethods];
1414
}
1515
@end
16+
17+
// TODO: Remove this after Xcode 14.3 is required
18+
@implementation WKWebView (CapacitorInspectablity)
19+
20+
- (void)setInspectableIfRequired: (BOOL)shouldInspect {
21+
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 160400
22+
if (@available(iOS 16.4, *)) {
23+
self.inspectable = shouldInspect;
24+
}
25+
#endif
26+
}
27+
28+
@end

0 commit comments

Comments
 (0)