-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathForemWebView+WKScriptMessageHandler.swift
More file actions
161 lines (143 loc) · 6.49 KB
/
ForemWebView+WKScriptMessageHandler.swift
File metadata and controls
161 lines (143 loc) · 6.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#if os(iOS)
import UIKit
import WebKit
import AlamofireImage
import YPImagePicker
enum BridgeMessageType: String {
case podcast = "podcast"
case video = "video"
case imageUpload = "imageUpload"
case coverImageUpload = "coverUpload"
}
extension ForemWebView: WKScriptMessageHandler {
public func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
switch message.name {
case "podcast":
if let podcast: Podcast = MessageParser().parse(json: message.body) {
mediaManager.handle(podcast)
}
// mediaManager.handlePodcastMessage(message.body as? [String: String] ?? [:])
case "video":
mediaManager.handleVideoMessage(message.body as? [String: String] ?? [:])
case "imageUpload":
handleImagePicker(message.body as? [String: String] ?? [:], type: .imageUpload)
case "coverUpload":
handleImagePicker(message.body as? [String: String] ?? [:], type: .coverImageUpload)
case "haptic":
guard let hapticType = message.body as? String else { return }
handleHapticMessage(type: hapticType)
case "userLogout":
foremWebViewDelegate?.didLogout(userData: self.userData)
ensureForemInstance()
case "userLogin":
if let messageData = message.body as? [String: Any] {
let foremUser = ForemUserData(message: messageData)
self.userData = foremUser
foremWebViewDelegate?.didLogin(userData: foremUser)
ensureForemInstance()
}
default:
break
}
}
// Helper function that will send Bridge messages into the DOM
internal func sendBridgeMessage(_ message: [String: String], type: BridgeMessageType) {
// Add the namespace to the payload
var payload = message
payload["namespace"] = type.rawValue
var jsonString = ""
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(payload) {
jsonString = String(data: jsonData, encoding: .utf8) ?? ""
}
let javascript = "window.ForemMobile?.injectJSMessage('\(jsonString)')"
evaluateJavaScript(wrappedJS(javascript)) { _, error in
if let error = error {
print("Error sending '\(type.rawValue)' message (\(message)): \(error.localizedDescription)")
}
}
}
private func handleHapticMessage(type: String) {
switch type {
case "heavy":
let heavyImpact = UIImpactFeedbackGenerator(style: .heavy)
heavyImpact.impactOccurred()
case "light":
let lightImpact = UIImpactFeedbackGenerator(style: .light)
lightImpact.impactOccurred()
case "medium":
let mediumImpact = UIImpactFeedbackGenerator(style: .medium)
mediumImpact.impactOccurred()
default:
let notification = UINotificationFeedbackGenerator()
notification.notificationOccurred(.success)
}
}
// MARK: - Image Uploads
// Builds, configures and returns an YPImagePicker
func imagePicker(_ ratio: String?) -> YPImagePicker {
var config = YPImagePickerConfiguration()
config.shouldSaveNewPicturesToAlbum = false
config.startOnScreen = YPPickerScreen.library
config.library.onlySquare = false
config.library.isSquareByDefault = false
if let ratio = ratio, let rectangleRatio = Double(ratio) {
config.showsCrop = .rectangle(ratio: rectangleRatio)
}
config.library.mediaType = YPlibraryMediaType.photo
return YPImagePicker(configuration: config)
}
// Whenever a request to select an image is triggered via WKScriptMessageHandler
func handleImagePicker(_ message: [String: String], type: BridgeMessageType) {
let picker = imagePicker(message["ratio"])
// Dark NavigationBar temporary fix (iOS 15 + XCode13):
// https://github.com/Yummypets/YPImagePicker/issues/690#issuecomment-926587214
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
picker.navigationBar.scrollEdgeAppearance = navBarAppearance
picker.didFinishPicking { [unowned picker] items, _ in
// Callback for when the native image picker process is completed by the user
if let photo = items.singlePhoto {
// Image selected now start uploading process
let message = ["action": "uploading"]
self.sendBridgeMessage(message, type: type)
self.uploadImage(photo.image, type: type)
}
picker.dismiss(animated: true, completion: nil)
}
// Use 'foremWebViewDelegate' as the 'pivot' ViewController to present the native picker
if let delegateViewController = foremWebViewDelegate as? UIViewController {
delegateViewController.present(picker, animated: true, completion: nil)
}
}
// Function that will upload a UIImage directly to the Forem instance
func uploadImage(_ image: UIImage, type: BridgeMessageType) {
guard let domain = self.foremInstance?.domain else {
let message = ["action": "error", "message": "Unexpected error"]
self.sendBridgeMessage(message, type: type)
return
}
// Support the simulator
let requestProtocol = domain == "localhost:3000" ? "http://" : "https://"
let targetUrl = "\(requestProtocol)\(domain)/image_uploads"
let optimizedImage = image.af.imageScaled(to: image.foremLimitedSize())
// Get fresh CSRF token for image upload request
self.fetchCSRF { token in
guard let token = token else { return }
optimizedImage.uploadTo(url: targetUrl, token: token) { (link, error) in
if let link = link as String? {
var message = ["action": "success", "link": link]
if !link.contains(requestProtocol) {
message["link"] = "\(requestProtocol)\(domain)\(link)"
}
self.sendBridgeMessage(message, type: type)
} else {
let message = ["action": "error", "error": error ?? "Unexpected error"]
self.sendBridgeMessage(message, type: type)
}
}
}
}
}
#endif