-
Notifications
You must be signed in to change notification settings - Fork 0
/
AddCourseViewController.swift
397 lines (303 loc) · 14 KB
/
AddCourseViewController.swift
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
//
// AddCourseViewController.swift
// myCourse
//
// Class to add course from the tableview to icloud private database. Advanced function is setup for iBeacon function which allow location based feature to save student course data to public database and query by studentid and beanname
//
// Created by Leon Lum on 17/05/20.
// Edited by Leon Lum, Kyle He on 17/06/15
// Copyright © 2017 Extreme. All rights reserved.
//
import UIKit
import CloudKit
import Bean_iOS_OSX_SDK
class AddCourseViewController: UIViewController, PTDBeanDelegate, PTDBeanManagerDelegate {
// let myContainer = CKContainer.default()
let myContainer = CKContainer(identifier: "iCloud.com.appglory.myCourse")
var publicDB: CKDatabase!
var privateDB: CKDatabase!
let cloudstatus = CloudAccount.checkcloudlogin()
@IBOutlet weak var cancelButton: UIBarButtonItem!
@IBOutlet weak var saveButton: UIBarButtonItem!
//Define IBOutlet for course id and text
@IBOutlet weak var courseIdTextField: UITextField!
@IBOutlet weak var courseNameTextField: UITextField!
//Define IBOutlet for Switch button
@IBOutlet weak var advancedSwitch: UISwitch!
@IBOutlet weak var textSwitch: UILabel!
//Define IBOutlet for courseview
@IBOutlet var addCourseView: UIView!
//Define IBOutlet for studend id
@IBOutlet weak var studentIdTextField: UITextField!
//Define stackview for hide or unhide when detecting bean
@IBOutlet weak var studentInfo: UIStackView!
//Define control for bean function
@IBOutlet weak var BeanButton: UIButton!
//Define Alert controller
var alert: UIAlertController!
//Define current CKrecord
var currentRecord: CKRecord?
//Define variables for beanmanager
var beanManager: PTDBeanManager?
//Define Bean object
var yourBean: PTDBean?
//Define beanname
var beanName: String?
//Define scan error
var scanError: NSError?
// define userDefaults
let userDefault = UserDefaults.standard
//Define constant for user default of switching advaned function
let switchKeyConstant = "AdvancedOnOff"
let textAdvancedKeyConstant = "AdvancedText"
let textAdvancedOnlabel = "Advanced mode is On"
let textAdvancedOfflabel = "Advanced mode is Off"
let message = "Sign in to your iCloud account to write records. On the Home screen, launch Settings, tap iCloud, and enter your Apple ID. Turn iCloud Drive on. If you don't have an iCloud account, tap Create a new Apple ID."
//MARK: function to load after loading the view.
override func viewDidLoad() {
super.viewDidLoad()
publicDB = myContainer.publicCloudDatabase
privateDB = myContainer.privateCloudDatabase
//Define imageview and set to background
let imageView = UIImageView(frame: self.view.bounds);
imageView.image = UIImage(named: "footer_8.jpg")
self.addCourseView.addSubview(imageView)
self.addCourseView.sendSubview(toBack: imageView)
if !cloudstatus.isEmpty {
createAlert(title: "Attention", text: cloudstatus)
}
//START Beacon function setup
studentInfo.isHidden = true
//set initial label for switch text
if let textFieldValue = userDefault.string(forKey: switchKeyConstant) {
textSwitch.text = textFieldValue
} else{
textSwitch.text = textAdvancedOfflabel
}
//set status of switch text from userdefault value
if (userDefault.bool(forKey: switchKeyConstant)) {
advancedSwitch.isOn = true
textSwitch.text = textAdvancedOnlabel
} else {
advancedSwitch.isOn = false
textSwitch.text = textAdvancedOfflabel
}
//allow advanced function if switch is set on
if advancedSwitch.isOn {
runAdvanced ()
}
//END Beacon function Setup
}
//MARK: function to start the iBeacon
private func runAdvanced (){
// Create instance of PTDBeanManager and assign as the delegate
beanManager = PTDBeanManager()
beanManager!.delegate = self as PTDBeanManagerDelegate
//Define double tap gesture recognizer for Beanbutton to add record to cloudkit
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
tapRecognizer.numberOfTapsRequired = 2
BeanButton.addGestureRecognizer(tapRecognizer)
}
//MARK: function when switch button clicked
@IBAction func clickSwitch(_ sender: UISwitch) {
if advancedSwitch.isOn == true {
//set value to false
textSwitch.text = textAdvancedOfflabel
advancedSwitch.isOn = false
//hide student info stackview
studentInfo.isHidden = true
//update default value to false
userDefault.setValue(textSwitch.text, forKey: textAdvancedKeyConstant)
userDefault.set(advancedSwitch.isOn, forKey: switchKeyConstant)
//set the switch
advancedSwitch.setOn(false, animated:true)
} else {
//set value to false
textSwitch.text = textAdvancedOnlabel
advancedSwitch.isOn = true
//update default value to true
userDefault.setValue(textSwitch.text, forKey: textAdvancedKeyConstant)
userDefault.set(advancedSwitch.isOn, forKey: switchKeyConstant)
runAdvanced ()
//set the switch
advancedSwitch.setOn(true, animated:true)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: function for cancel button
@IBAction func cancelButtonTapped(_ sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
}
//MARK: function to check icloud container availability and take action
@IBAction func saveButtonTapped(_ sender: UIBarButtonItem) {
if !cloudstatus.isEmpty {
createAlert(title: "Attention", text: cloudstatus)
}else {
saveCoursetoPrivateDB()
}
}
//MARK: function for save course data to coredata
private func saveCoursetoPrivateDB(){
//prevent multiple save
cancelButton.isEnabled = false
saveButton.isEnabled = false
let course=CKRecord(recordType: "Course")
course.setObject(self.courseIdTextField.text as CKRecordValue?, forKey: "ID")
course.setObject(self.courseNameTextField.text as CKRecordValue?, forKey: "Name")
if !(courseIdTextField.text?.isEmpty)! && !(courseNameTextField.text?.isEmpty)! {
privateDB.save(course) { (saveRecord, error) in
if error != nil{
print (error?.localizedDescription ?? "")
//put to main thread
OperationQueue.main.addOperation {
self.createAlert(title: "Attention", text: self.message)
}
}
else
{
OperationQueue.main.addOperation {
// self.present(self.alert,animated: true, completion: nil)
self.createAlert(title: "Congratulation", text: "You have successfully created a new course!")
self.courseIdTextField.text = nil
self.courseNameTextField.text = nil
print("Data Save to CloudKit successfully!")
}
}
}
} else{
//display alert is field is empty
self.createAlert(title: "Attention", text: "Empty content is not saved!")
}
}
//MARK: function to get the course from cloud
@IBAction func scanCourse(_ sender: Any) {
if !cloudstatus.isEmpty {
createAlert(title: "Attention", text: cloudstatus)
}else {
//Perform search function from cloudkit
predicatequery()
}
}
//MARK: function to perform query by predicate
private func predicatequery(){
//Define predicate for search, put studentid and beanname
let enrollPredicate = NSPredicate(format: "studentid = %@ AND beanid =%@", studentIdTextField.text!, yourBean?.name ?? "")
//Define query
let enrollquery = CKQuery(recordType: "CourseStudent", predicate: enrollPredicate)
//Perform query to public database
publicDB.perform(enrollquery, inZoneWith: nil) { (results, error) in
if (error != nil) {
//display error
DispatchQueue.main.async(){
self.createAlert(title:"Cloud Access Error", text: error!.localizedDescription)
}
}else {
//display value to input field
if results!.count > 0 {
let record = results! [0]
self.currentRecord = record
DispatchQueue.main.async(){
self.courseIdTextField.text = record.object(forKey: "courseid") as? String
self.courseNameTextField.text = record.object(forKey: "coursename") as? String
}
}else {
//empty current field when no record found
DispatchQueue.main.async(){
self.createAlert(title: "No Match Found", text: "This Studentid is not enrolled")
self.courseIdTextField.text = nil
self.courseNameTextField.text = nil
}
}
}
}
}
//Bean SDK: check to see if Bluetooth is on
func beanManagerDidUpdateState(_ beanManager: PTDBeanManager!) {
//start scan for bean
startScanning()
if beanManager!.state == BeanManagerState.poweredOn {
//handle error
if let e = scanError {
print(e)
}
} else{
//crete alert when bluetooth not poweron
if (userDefault.bool(forKey: switchKeyConstant)) {
createAlert(title: "Attention", text: "Auto-mapping, please turn on bluetooth")
}
}
}
//MARK: function to create alert view
func createAlert(title: String, text: String) {
//define alert, set title and message
let alert = UIAlertController(title: title, message: text, preferredStyle: .alert)
//add action for tapping on "delete all" button
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
self.saveButton.isEnabled = true
self.cancelButton.isEnabled = true
}))
//present the alert
self.present(alert, animated:true, completion: nil)
}
//MARK: Scan for Beans
func startScanning() {
var error: NSError?
beanManager!.startScanning(forBeans_error: &error)
}
//MARK: Connect to a specific Bean
func beanManager(_ beanManager: PTDBeanManager!, didDiscover bean: PTDBean!, error: Error!) {
if let e = error{
print(e)
}
if bean.name == "CowBean" {
yourBean = bean
//Unhide Student Info when bean found
if (yourBean?.name.isEmpty)! {
studentInfo.isHidden = true
} else {
studentInfo.isHidden = false
print(yourBean?.name ?? "")
}
}
}
//MARK: function for double tap gesture to save record to public database when iCloud container is available
@IBAction func doubleTapped(_ sender:UITapGestureRecognizer){
if !cloudstatus.isEmpty {
createAlert(title: "Attention", text: cloudstatus)
} else {
saveCoursetoPublicDB()
}
}
//MARK: func to save coursestudent records to publidDB
private func saveCoursetoPublicDB(){
//For demonstration purpose, set beanid with the name of the testing Bean used
let beanid = "CowBean"
//Define public data
let publicData = CKRecord(recordType: "CourseStudent")
publicData.setObject(self.courseIdTextField.text as CKRecordValue?, forKey: "courseid")
publicData.setObject(self.courseNameTextField.text as CKRecordValue?, forKey: "coursename")
publicData.setObject(self.studentIdTextField.text as CKRecordValue?, forKey: "studentid")
publicData.setObject(beanid as CKRecordValue, forKey: "beanid")
//set to check the fields is not empty when saving data
if !(courseIdTextField.text?.isEmpty)! && !(courseNameTextField.text?.isEmpty)! && !(studentIdTextField.text?.isEmpty)! && !beanid.isEmpty {
publicDB.save(publicData) { (saveRecord, error) in
if error != nil{
OperationQueue.main.addOperation {
self.createAlert(title: "Attention", text: (error?.localizedDescription)!)
}
print("error saving ---" + (error?.localizedDescription)!)
}else{
OperationQueue.main.addOperation {
self.createAlert(title: "Attention", text: "Records successfully added!")
}
}
}
self.studentIdTextField.text = nil
} else{
self.createAlert(title: "Attention", text: "Empty content is not saved.")
}
}
}