Skip to content

Commit bacf367

Browse files
Add Swift code snippets to Fabric native component iOS documentation
- Added tabbed code examples (Objective-C/Swift) for iOS Fabric components - Implemented complete Swift version of RCTWebView class - Maintains consistency with Android documentation structure (Java/Kotlin tabs) - Fixes #4897
1 parent 91b4667 commit bacf367

1 file changed

Lines changed: 120 additions & 2 deletions

File tree

docs/fabric-native-components-ios.md

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ Demo
7070

7171
After creating the header file and the implementation file, you can start implementing them.
7272

73-
This is the code for the `RCTWebView.h` file, which declares the component interface.
73+
This is the code for the header file, which declares the component interface.
74+
75+
<Tabs groupId="ios-language" queryString defaultValue={constants.defaultAppleLanguage} values={constants.appleLanguages}>
76+
<TabItem value="objc">
7477

7578
```objc title="Demo/RCTWebView/RCTWebView.h"
7679
#import <React/RCTViewComponentView.h>
@@ -87,9 +90,28 @@ NS_ASSUME_NONNULL_BEGIN
8790
NS_ASSUME_NONNULL_END
8891
```
8992

93+
</TabItem>
94+
<TabItem value="swift">
95+
96+
```swift title="Demo/RCTWebView/RCTWebView.swift"
97+
import React
98+
import UIKit
99+
100+
@objc(RCTWebView)
101+
class RCTWebView: RCTViewComponentView {
102+
// You would declare native methods you'd want to access from the view here
103+
}
104+
```
105+
106+
</TabItem>
107+
</Tabs>
108+
90109
This class defines an `RCTWebView` which extends the `RCTViewComponentView` class. This is the base class for all the native components and it is provided by React Native.
91110

92-
The code for the implementation file (`RCTWebView.mm`) is the following:
111+
The code for the implementation file is the following:
112+
113+
<Tabs groupId="ios-language" queryString defaultValue={constants.defaultAppleLanguage} values={constants.appleLanguages}>
114+
<TabItem value="objc">
93115

94116
```objc title="Demo/RCTWebView/RCTWebView.mm"
95117
#import "RCTWebView.h"
@@ -184,6 +206,102 @@ using namespace facebook::react;
184206
@end
185207
```
186208
209+
</TabItem>
210+
<TabItem value="swift">
211+
212+
```swift title="Demo/RCTWebView/RCTWebView.swift"
213+
import React
214+
import WebKit
215+
216+
@objc(RCTWebView)
217+
class RCTWebView: RCTViewComponentView {
218+
private var sourceURL: URL?
219+
private var webView: WKWebView!
220+
221+
override init(frame: CGRect) {
222+
super.init(frame: frame)
223+
setupWebView()
224+
}
225+
226+
required init?(coder: NSCoder) {
227+
super.init(coder: coder)
228+
setupWebView()
229+
}
230+
231+
private func setupWebView() {
232+
// highlight-start
233+
webView = WKWebView()
234+
webView.navigationDelegate = self
235+
addSubview(webView)
236+
// highlight-end
237+
}
238+
239+
override func updateProps(_ props: Props, oldProps: Props) {
240+
guard let oldViewProps = _props as? CustomWebViewProps,
241+
let newViewProps = props as? CustomWebViewProps else {
242+
super.updateProps(props, oldProps: oldProps)
243+
return
244+
}
245+
246+
// Handle your props here
247+
if oldViewProps.sourceURL != newViewProps.sourceURL {
248+
let urlString = String(cString: newViewProps.sourceURL)
249+
sourceURL = URL(string: urlString)
250+
// highlight-start
251+
if urlIsValid(newViewProps.sourceURL) {
252+
if let url = sourceURL {
253+
webView.load(URLRequest(url: url))
254+
}
255+
}
256+
// highlight-end
257+
}
258+
259+
super.updateProps(props, oldProps: oldProps)
260+
}
261+
262+
override func layoutSubviews() {
263+
super.layoutSubviews()
264+
webView.frame = bounds
265+
}
266+
267+
// highlight-start
268+
private func urlIsValid(_ propString: String) -> Bool {
269+
if !propString.isEmpty && sourceURL == nil {
270+
let result = CustomWebViewEventEmitter.OnScriptLoaded(
271+
result: .error
272+
)
273+
eventEmitter.onScriptLoaded(result)
274+
return false
275+
}
276+
return true
277+
}
278+
279+
private var eventEmitter: CustomWebViewEventEmitter {
280+
return _eventEmitter as! CustomWebViewEventEmitter
281+
}
282+
// highlight-end
283+
284+
@objc static func componentDescriptorProvider() -> ComponentDescriptorProvider {
285+
return concreteComponentDescriptorProvider<CustomWebViewComponentDescriptor>()
286+
}
287+
}
288+
289+
// MARK: - WKNavigationDelegate
290+
extension RCTWebView: WKNavigationDelegate {
291+
// highlight-start
292+
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
293+
let result = CustomWebViewEventEmitter.OnScriptLoaded(
294+
result: .success
295+
)
296+
eventEmitter.onScriptLoaded(result)
297+
}
298+
// highlight-end
299+
}
300+
```
301+
302+
</TabItem>
303+
</Tabs>
304+
187305
This code is written in Objective-C++ and contains various details:
188306

189307
- the `@interface` implements two protocols:

0 commit comments

Comments
 (0)