Skip to content

Commit 1367d93

Browse files
3.26-beta - Replace deprecated webview with WKWebView
1 parent 7eac75e commit 1367d93

File tree

6 files changed

+262
-114
lines changed

6 files changed

+262
-114
lines changed

Questions.xcodeproj/project.pbxproj

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
/* Begin PBXBuildFile section */
2424
650DE5F82128A62000FF6A0F /* SearchTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650DE5F72128A62000FF6A0F /* SearchTableViewController.swift */; };
25+
651F569326592CC0003D408C /* WKWebKit+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 651F569226592CC0003D408C /* WKWebKit+Extension.swift */; };
26+
651F569526592CDA003D408C /* QuestionWithAnswersForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 651F569426592CDA003D408C /* QuestionWithAnswersForm.swift */; };
2527
653D056F1D43CD2D00865D43 /* QuestionsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653D056E1D43CD2D00865D43 /* QuestionsUITests.swift */; };
2628
65456AED1D2BBEF90048965E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 65456AEF1D2BBEF90048965E /* Localizable.strings */; };
2729
65456AF21D2BC01C0048965E /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65456AF11D2BC01C0048965E /* String+Extension.swift */; };
@@ -104,6 +106,8 @@
104106
/* Begin PBXFileReference section */
105107
650745EF1EACCDF200BC178E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
106108
650DE5F72128A62000FF6A0F /* SearchTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTableViewController.swift; sourceTree = "<group>"; };
109+
651F569226592CC0003D408C /* WKWebKit+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WKWebKit+Extension.swift"; sourceTree = "<group>"; };
110+
651F569426592CDA003D408C /* QuestionWithAnswersForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestionWithAnswersForm.swift; sourceTree = "<group>"; };
107111
653D056C1D43CD2D00865D43 /* QuestionsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QuestionsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
108112
653D056E1D43CD2D00865D43 /* QuestionsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestionsUITests.swift; sourceTree = "<group>"; };
109113
653D05701D43CD2D00865D43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -199,6 +203,14 @@
199203
/* End PBXFrameworksBuildPhase section */
200204

201205
/* Begin PBXGroup section */
206+
651F569126592CA3003D408C /* WKWebKit */ = {
207+
isa = PBXGroup;
208+
children = (
209+
651F569226592CC0003D408C /* WKWebKit+Extension.swift */,
210+
);
211+
name = WKWebKit;
212+
sourceTree = "<group>";
213+
};
202214
6533008921D54D6B00007C1A /* Topics */ = {
203215
isa = PBXGroup;
204216
children = (
@@ -420,6 +432,7 @@
420432
65E12DA221C279FE0067B4D0 /* Extensions */ = {
421433
isa = PBXGroup;
422434
children = (
435+
651F569126592CA3003D408C /* WKWebKit */,
423436
6533009121D54E7700007C1A /* UIKit */,
424437
6533008E21D54DFF00007C1A /* Foundation */,
425438
8E30C75D1D351E6000CD32B0 /* AVAudioPlayer+Extension.swift */,
@@ -436,6 +449,7 @@
436449
65746A5A20B62B8900F28769 /* TopicEntry.swift */,
437450
8E7F0EFB1D351CEA0048F1A0 /* SetOfTopics.swift */,
438451
6548F085208896FA005A87D9 /* CommunityTopics.swift */,
452+
651F569426592CDA003D408C /* QuestionWithAnswersForm.swift */,
439453
);
440454
path = Models;
441455
sourceTree = "<group>";
@@ -737,10 +751,12 @@
737751
65646CDD21DF967F009C2695 /* ApplyProtocol.swift in Sources */,
738752
8E7F0EFC1D351CEA0048F1A0 /* SetOfTopics.swift in Sources */,
739753
65456AF41D2BC9620048965E /* TopicsViewController.swift in Sources */,
754+
651F569326592CC0003D408C /* WKWebKit+Extension.swift in Sources */,
740755
65F4207F1E835A4F00BE90F0 /* QRScannerViewController.swift in Sources */,
741756
65456FF81D77A07A004A13B6 /* Colors+Extension.swift in Sources */,
742757
6583F2DB224ADF9A0061F77D /* SideVolumeHUD.swift in Sources */,
743758
6583F2DC224ADF9A0061F77D /* SideVolumeHUDHolderView.swift in Sources */,
759+
651F569526592CDA003D408C /* QuestionWithAnswersForm.swift in Sources */,
744760
65479F11206A52EB0042790F /* Image+Extension.swift in Sources */,
745761
65746A5720B62A2400F28769 /* Topic.swift in Sources */,
746762
65AF1D0421C8E94E001C68E7 /* Bundle+Extension.swift in Sources */,
@@ -1008,7 +1024,7 @@
10081024
"$(inherited)",
10091025
"@executable_path/Frameworks",
10101026
);
1011-
MARKETING_VERSION = "3.25.1-beta";
1027+
MARKETING_VERSION = "3.26-beta";
10121028
PRODUCT_BUNDLE_IDENTIFIER = "com.illescas-Daniel.QuestionsApp";
10131029
PRODUCT_NAME = Questions;
10141030
PROVISIONING_PROFILE = "";
@@ -1032,7 +1048,7 @@
10321048
"$(inherited)",
10331049
"@executable_path/Frameworks",
10341050
);
1035-
MARKETING_VERSION = "3.25.1-beta";
1051+
MARKETING_VERSION = "3.26-beta";
10361052
PRODUCT_BUNDLE_IDENTIFIER = "com.illescas-Daniel.QuestionsApp";
10371053
PRODUCT_NAME = Questions;
10381054
PROVISIONING_PROFILE = "";

Questions/Base.lproj/Main.storyboard

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -604,34 +604,20 @@
604604
<objects>
605605
<viewController id="GVC-2t-1NK" customClass="WebTopicCreatorViewController" customModule="Questions" customModuleProvider="target" sceneMemberID="viewController">
606606
<view key="view" contentMode="scaleToFill" id="Fnd-kV-Mxx">
607-
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
607+
<rect key="frame" x="0.0" y="0.0" width="375" height="724"/>
608608
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
609-
<subviews>
610-
<webView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KPG-ob-CI3">
611-
<rect key="frame" x="0.0" y="140" width="375" height="638"/>
612-
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
613-
</webView>
614-
</subviews>
615609
<viewLayoutGuide key="safeArea" id="tgE-0Y-972"/>
616610
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
617-
<constraints>
618-
<constraint firstItem="KPG-ob-CI3" firstAttribute="top" secondItem="tgE-0Y-972" secondAttribute="top" id="7v0-Dk-Ces"/>
619-
<constraint firstItem="tgE-0Y-972" firstAttribute="trailing" secondItem="KPG-ob-CI3" secondAttribute="trailing" id="Dj9-j6-mQx"/>
620-
<constraint firstItem="KPG-ob-CI3" firstAttribute="leading" secondItem="tgE-0Y-972" secondAttribute="leading" id="EZy-dL-wnA"/>
621-
<constraint firstItem="KPG-ob-CI3" firstAttribute="centerX" secondItem="tgE-0Y-972" secondAttribute="centerX" id="FSk-4U-uZl"/>
622-
<constraint firstItem="tgE-0Y-972" firstAttribute="bottom" secondItem="KPG-ob-CI3" secondAttribute="bottom" id="KaH-iZ-dPi"/>
623-
<constraint firstItem="KPG-ob-CI3" firstAttribute="centerY" secondItem="tgE-0Y-972" secondAttribute="centerY" id="iub-Ks-rPZ"/>
624-
</constraints>
625611
</view>
626-
<navigationItem key="navigationItem" title="Topic Creator" largeTitleDisplayMode="always" id="L4T-er-ZLU">
612+
<navigationItem key="navigationItem" title="Topic Creator" largeTitleDisplayMode="never" id="L4T-er-ZLU">
627613
<barButtonItem key="rightBarButtonItem" systemItem="action" id="xa1-00-1O2">
628614
<connections>
629615
<action selector="outputBarButtonAction:" destination="GVC-2t-1NK" id="GzU-cu-gO0"/>
630616
</connections>
631617
</barButtonItem>
632618
</navigationItem>
619+
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" translucent="NO" prompted="NO"/>
633620
<connections>
634-
<outlet property="webView" destination="KPG-ob-CI3" id="AsP-gq-ADC"/>
635621
<segue destination="Jt3-KL-cf1" kind="unwind" identifier="unwindToTopics" unwindAction="unwindToTopics:" id="nt2-fz-uCk"/>
636622
</connections>
637623
</viewController>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//
2+
// WKWebKit+Extension.swift
3+
// Questions
4+
//
5+
// Created by Daniel Illescas Romero on 22/5/21.
6+
// Copyright © 2021 Daniel Illescas Romero. All rights reserved.
7+
//
8+
9+
import WebKit
10+
11+
extension WKWebView {
12+
13+
func inputValueFrom(id: String, completionHandler: @escaping (String?) -> Void) -> String? {
14+
self.evaluateJavaScript(#"document.getElementById("\#(id)").value"#) { value, error in
15+
completionHandler(value as? String)
16+
}
17+
return nil
18+
}
19+
20+
func multipleInputValuesFrom(ids: [String], completionHandler: @escaping ([String?]) -> Void) {
21+
var getElementByIds: [String] = []
22+
for id in ids {
23+
getElementByIds.append(#"document.getElementById("\#(id)").value"#)
24+
}
25+
26+
self.evaluateJavaScript("[\(getElementByIds.joined(separator: ", "))]") { jsValue, error in
27+
guard let values = jsValue as? Array<Any> else {
28+
completionHandler([])
29+
return
30+
}
31+
var stringValues: [String?] = []
32+
for value in values {
33+
stringValues.append(value as? String)
34+
}
35+
completionHandler(stringValues)
36+
}
37+
}
38+
39+
func isCheckboxChecked(id: String, completionHandler: @escaping (Bool) -> Void) -> String? {
40+
self.evaluateJavaScript(#"document.getElementById("\#(id)").checked"#) { value, error in
41+
if let evaluatedOutput = value as? Bool, evaluatedOutput {
42+
completionHandler(true)
43+
} else {
44+
completionHandler(false)
45+
}
46+
}
47+
return nil
48+
}
49+
50+
func checkedCheckboxes(ids: [String], completionHandler: @escaping ([Bool]) -> Void) {
51+
52+
var getElementByIds: [String] = []
53+
for id in ids {
54+
getElementByIds.append(#"document.getElementById("\#(id)").checked"#)
55+
}
56+
57+
self.evaluateJavaScript("[\(getElementByIds.joined(separator: ", "))]") { jsValue, error in
58+
guard let checkedCheckboxes = jsValue as? Array<Bool> else {
59+
completionHandler([])
60+
return
61+
}
62+
completionHandler(checkedCheckboxes)
63+
}
64+
}
65+
66+
func questionAndAnswers(
67+
questionAndAnswersIDs: QuestionsWithAnswersIDs,
68+
completionHandler: @escaping ([QuestionWithAnswersForm]) -> Void
69+
) {
70+
71+
var elementsByID: [String] = []
72+
for (questionID, questionImageID, answerIDs) in questionAndAnswersIDs {
73+
74+
var answersByID: [String] = []
75+
76+
for (answerID, isCorrectID) in answerIDs {
77+
answersByID.append(#"{ answer: document.getElementById("\#(answerID)").value, isCorrect: document.getElementById("\#(isCorrectID)").checked }"#)
78+
}
79+
let answers = "[\(answersByID.joined(separator: ", "))]"
80+
81+
let questionImageByID = #"document.getElementById("\#(questionImageID)").value"#
82+
83+
elementsByID.append(#"{ question: document.getElementById("\#(questionID)").value, questionImage: \#(questionImageByID), answers: \#(answers) }"#)
84+
}
85+
86+
self.evaluateJavaScript("[\(elementsByID.joined(separator: ", "))]") { jsValue, error in
87+
guard let values = jsValue as? Array<Any> else {
88+
completionHandler([])
89+
return
90+
}
91+
92+
let questionsWithAnswers = try? JSONDecoder().decode([QuestionWithAnswersForm].self, from: JSONSerialization.data(withJSONObject: values, options: .fragmentsAllowed))
93+
94+
completionHandler(questionsWithAnswers ?? [])
95+
}
96+
}
97+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// QuestionWithAnswers.swift
3+
// Questions
4+
//
5+
// Created by Daniel Illescas Romero on 22/5/21.
6+
// Copyright © 2021 Daniel Illescas Romero. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
struct QuestionWithAnswersForm: Decodable {
12+
13+
struct Answer: Decodable {
14+
let answer: String
15+
let isCorrect: Bool
16+
}
17+
18+
let question: String
19+
let questionImage: String?
20+
let answers: [Answer]
21+
}
22+
23+
typealias QuestionsWithAnswersIDs = [(questionID: String, questionImageID: String, answerIDs: [(answerValueID: String, isAnswerCorrectID: String)])]

0 commit comments

Comments
 (0)