Skip to content

Commit 9e7f975

Browse files
v2.13-beta:
- Added quick home action for QR Code - Now the app present an alert if the QR format is wrong
1 parent 3f84d3c commit 9e7f975

16 files changed

+107
-39
lines changed

Questions/AppDelegate.swift

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
88

99
// Home Screen Quick Actions [3D Touch]
1010

11+
enum ShortcutItemType: String {
12+
case QRCode
13+
case DarkTheme
14+
case LightTheme
15+
}
16+
1117
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
1218

1319
// Load configuration file (if it doesn't exist it creates a new one when the app goes to background)
@@ -17,42 +23,56 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1723

1824
if #available(iOS 9.0, *) {
1925

20-
let darkTheme = UIMutableApplicationShortcutItem(type: "DarkTheme",
26+
let readQRCode = UIMutableApplicationShortcutItem(type: ShortcutItemType.QRCode.rawValue,
27+
localizedTitle: "Read QR Code".localized,
28+
localizedSubtitle: nil,
29+
icon: UIApplicationShortcutIcon(templateImageName: "QRCodeIcon"),
30+
userInfo: nil)
31+
32+
let darkTheme = UIMutableApplicationShortcutItem(type: ShortcutItemType.DarkTheme.rawValue,
2133
localizedTitle: "Dark Theme".localized,
2234
localizedSubtitle: nil,
2335
icon: UIApplicationShortcutIcon(templateImageName: "DarkThemeIcon"),
2436
userInfo: nil)
2537

26-
let lightTheme = UIMutableApplicationShortcutItem(type: "LightTheme",
38+
let lightTheme = UIMutableApplicationShortcutItem(type: ShortcutItemType.LightTheme.rawValue,
2739
localizedTitle: "Light Theme".localized,
2840
localizedSubtitle: nil,
2941
icon: UIApplicationShortcutIcon(templateImageName: "LightThemeIcon"),
3042
userInfo: nil)
3143

32-
application.shortcutItems = [darkTheme, lightTheme]
44+
application.shortcutItems = [readQRCode, darkTheme, lightTheme]
3345
}
3446

3547
return true
3648
}
3749

38-
enum ShortcutItemType: String {
39-
case DarkTheme
40-
case LightTheme
41-
}
50+
4251

4352
@available(iOS 9.0, *)
4453
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
4554

4655
if let itemType = ShortcutItemType(rawValue: shortcutItem.type) {
56+
4757
switch itemType {
58+
case .QRCode:
59+
60+
let storyboard = UIStoryboard(name: "Main", bundle: nil)
61+
let viewController = storyboard.instantiateViewController(withIdentifier: "mainViewController") as! MainViewController
62+
63+
let navController = UINavigationController.init(rootViewController: viewController)
64+
window?.rootViewController?.present(navController, animated: false, completion: nil)
65+
66+
viewController.performSegue(withIdentifier: "QRScannerVC", sender: self)
67+
4868
case .DarkTheme:
4969
Settings.sharedInstance.darkThemeEnabled = true
5070
case .LightTheme:
5171
Settings.sharedInstance.darkThemeEnabled = false
5272
}
5373
}
5474
}
55-
75+
5676
func applicationDidEnterBackground(_ application: UIApplication) {
5777

5878
if Audio.bgMusic?.isPlaying ?? false {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"images" : [
3+
{
4+
"idiom" : "universal",
5+
"scale" : "1x"
6+
},
7+
{
8+
"idiom" : "universal",
9+
"filename" : "QRCodeIcon@2x.png",
10+
"scale" : "2x"
11+
},
12+
{
13+
"idiom" : "universal",
14+
"filename" : "QRCodeIcon@3x.png",
15+
"scale" : "3x"
16+
}
17+
],
18+
"info" : {
19+
"version" : 1,
20+
"author" : "xcode"
21+
}
22+
}
34 KB
Loading
61.6 KB
Loading

Questions/Base.lproj/Main.storyboard

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@
164164
</userDefinedRuntimeAttribute>
165165
</userDefinedRuntimeAttributes>
166166
<connections>
167-
<segue destination="I6B-9U-azf" kind="show" id="MLK-gp-ovr"/>
167+
<segue destination="I6B-9U-azf" kind="show" identifier="QRScannerVC" id="MLK-gp-ovr"/>
168168
</connections>
169169
</button>
170170
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="glT-nY-qNM">
@@ -210,9 +210,11 @@
210210
<outlet property="settingsButton" destination="49H-XB-RgC" id="wp2-0o-qhG"/>
211211
<outlet property="startButton" destination="arZ-7k-Uja" id="zAH-RX-Cfw"/>
212212
<outlet property="view" destination="Sbf-MR-kXR" id="98J-ov-5jm"/>
213+
<segue destination="SmG-TC-mxg" kind="unwind" identifier="unwindToQRScanner" unwindAction="unwindToQRScanner:" id="Oqx-qv-Z0k"/>
213214
</connections>
214215
</viewController>
215216
<placeholder placeholderIdentifier="IBFirstResponder" id="TTT-Cg-fex" userLabel="First Responder" sceneMemberID="firstResponder"/>
217+
<exit id="SmG-TC-mxg" userLabel="Exit" sceneMemberID="exit"/>
216218
</objects>
217219
<point key="canvasLocation" x="-199" y="483"/>
218220
</scene>
@@ -484,7 +486,7 @@ Incorrect answers: X
484486
<!--Scanner Controller-->
485487
<scene sceneID="ZsB-0h-1jt">
486488
<objects>
487-
<viewController id="I6B-9U-azf" customClass="QRScannerController" customModule="Questions" customModuleProvider="target" sceneMemberID="viewController">
489+
<viewController storyboardIdentifier="QRScannerVC" id="I6B-9U-azf" customClass="QRScannerController" customModule="Questions" customModuleProvider="target" sceneMemberID="viewController">
488490
<layoutGuides>
489491
<viewControllerLayoutGuide type="top" id="N5n-ZC-GmR"/>
490492
<viewControllerLayoutGuide type="bottom" id="eJ0-2H-qhf"/>
@@ -494,9 +496,9 @@ Incorrect answers: X
494496
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
495497
<subviews>
496498
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="enF-0f-cBp">
497-
<rect key="frame" x="108" y="350.66666666666669" width="198" height="36"/>
499+
<rect key="frame" x="111" y="350.66666666666669" width="192" height="36"/>
498500
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle3"/>
499-
<state key="normal" title="Allow Camera access!"/>
501+
<state key="normal" title="Allow Camera access"/>
500502
<connections>
501503
<action selector="allowCameraAction" destination="I6B-9U-azf" eventType="touchUpInside" id="Eho-Ae-oMO"/>
502504
</connections>

Questions/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>APPL</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>2.12-beta</string>
18+
<string>2.13-beta</string>
1919
<key>CFBundleSignature</key>
2020
<string>????</string>
2121
<key>CFBundleVersion</key>

Questions/LicensesViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ class LicensesViewController: UIViewController {
2020
setFrame()
2121

2222
NotificationCenter.default.addObserver(self, selector: #selector(setFrame),
23-
name: NSNotification.Name.UIApplicationDidChangeStatusBarOrientation, object: nil)
23+
name: Notification.Name.UIApplicationDidChangeStatusBarOrientation, object: nil)
2424

2525
NotificationCenter.default.addObserver(self, selector: #selector(loadCurrentTheme),
26-
name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
26+
name: Notification.Name.UIApplicationDidBecomeActive, object: nil)
2727
}
2828

2929
deinit {

Questions/MainViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ class MainViewController: UIViewController {
3434

3535
// If user rotates screen, the buttons position and sizes are recalculated
3636
NotificationCenter.default.addObserver(self, selector: #selector(setFramesAndPosition),
37-
name: NSNotification.Name.UIApplicationDidChangeStatusBarOrientation, object: nil)
37+
name: Notification.Name.UIApplicationDidChangeStatusBarOrientation, object: nil)
3838

3939
// Loads the theme if user uses a home quick action
4040
NotificationCenter.default.addObserver(self, selector: #selector(loadTheme),
41-
name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
41+
name: Notification.Name.UIApplicationDidBecomeActive, object: nil)
4242
}
4343

4444
override func viewWillAppear(_ animated: Bool) {

Questions/QRScannerViewController.swift

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,33 +40,46 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
4040

4141
captureSession.startRunning()
4242

43-
NotificationCenter.default.addObserver(self, selector: #selector(self.loadPreview),
44-
name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
43+
NotificationCenter.default.addObserver(self, selector: #selector(loadPreview),
44+
name: Notification.Name.UIDeviceOrientationDidChange, object: nil)
4545
}
4646
}
4747

4848
override func viewWillAppear(_ animated: Bool) {
49+
NotificationCenter.default.addObserver(self, selector: #selector(loadTheme),
50+
name: Notification.Name.UIApplicationDidBecomeActive, object: nil)
4951
loadTheme()
5052
}
5153

54+
deinit {
55+
if #available(iOS 9.0, *) { }
56+
else {
57+
NotificationCenter.default.removeObserver(self)
58+
}
59+
}
60+
5261
// MARK: AVCaptureMetadataOutputObjectsDelegate
5362

5463
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
5564

5665
if !codeIsRead {
5766

58-
let metadataObj = metadataObjects.first as! AVMetadataMachineReadableCodeObject
67+
let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject
5968

60-
if metadataObj.type == AVMetadataObjectTypeQRCode {
61-
62-
// READ JSON format
63-
64-
if let data = metadataObj.stringValue.data(using: .utf8) {
65-
let content = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [[String: Any]]
66-
performSegue(withIdentifier: "unwindToQuestions", sender: content)
67-
codeIsRead = true
68-
}
69+
guard let metadata = metadataObject, metadata.type == AVMetadataObjectTypeQRCode else { invalidQRCodeFormat(); return }
70+
guard let data = metadata.stringValue.data(using: .utf8) else { invalidQRCodeFormat(); return }
71+
72+
var content: [[String: Any]]?
73+
74+
do {
75+
content = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]]
76+
} catch { invalidQRCodeFormat(); } //return }
77+
78+
if let validContent = content {
79+
performSegue(withIdentifier: "unwindToQuestions", sender: validContent)
80+
codeIsRead = true
6981
}
82+
else { invalidQRCodeFormat(); }
7083
}
7184
}
7285

@@ -83,6 +96,8 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
8396

8497
@IBAction func unwindToQRScanner(_ segue: UIStoryboardSegue) { }
8598

99+
// MARK: Alerts
100+
86101
@IBAction func allowCameraAction() {
87102
let alertViewController = UIAlertController(title: "Attention".localized,
88103
message: "Camera access required for QR Scanning".localized,
@@ -123,4 +138,13 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
123138
view.backgroundColor = darkThemeEnabled ? .gray : .white
124139
allowCameraButton.setTitleColor(darkThemeEnabled ? .warmYellow : .coolBlue, for: .normal)
125140
}
141+
142+
func invalidQRCodeFormat() {
143+
let alertViewController = UIAlertController(title: "Attention".localized,
144+
message: "Invalid QR Code format",
145+
preferredStyle: .alert)
146+
147+
alertViewController.addAction(title: "OK".localized, style: .default, handler: nil)
148+
present(alertViewController, animated: true, completion: nil)
149+
}
126150
}

Questions/QuestionsViewController.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ class QuestionsViewController: UIViewController {
6060

6161
// If user minimize the app, the pause menu shows up
6262
NotificationCenter.default.addObserver(self, selector: #selector(showPauseMenu),
63-
name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
63+
name: Notification.Name.UIApplicationDidEnterBackground, object: nil)
6464

6565
// If user rotates screen, the buttons and labels position are recalculated, aswell as the bluerred background for the pause menu
6666
NotificationCenter.default.addObserver(self, selector: #selector(setButtonsAndLabelsPosition),
67-
name: NSNotification.Name.UIApplicationDidChangeStatusBarOrientation, object: nil)
67+
name: Notification.Name.UIApplicationDidChangeStatusBarOrientation, object: nil)
6868

6969
// Loads the theme if user uses a home quick action
7070
NotificationCenter.default.addObserver(self, selector: #selector(loadCurrentTheme),
71-
name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
71+
name: Notification.Name.UIApplicationDidBecomeActive, object: nil)
7272

7373
if Settings.sharedInstance.score < 5 {
7474
helpButton.alpha = 0.4

0 commit comments

Comments
 (0)