From 998684304bff9c389a60d5198a9b84aafe791175 Mon Sep 17 00:00:00 2001 From: Nithin Date: Sat, 28 Dec 2019 15:53:53 +0530 Subject: [PATCH 1/2] AESCrypt Integration --- Register.xcodeproj/project.pbxproj | 42 ++++- .../xcshareddata/xcschemes/Register.xcscheme | 98 ++++++++++ .../xcschemes/xcschememanagement.plist | 20 +++ Register/AESCrypt/AESCrypt-Bridging-Header.h | 6 + Register/AESCrypt/AESCrypt.swift | 169 ++++++++++++++++++ Register/AppDelegate.swift | 6 +- Register/Base.lproj/Main.storyboard | 122 ++++++++++++- Register/CoreData/DataManager.swift | 52 ++++++ .../Register.xcdatamodel/contents | 11 ++ .../Register.xcdatamodel/contents | 4 - Register/SceneDelegate.swift | 2 +- Register/StudentTableViewCell.swift | 28 +++ Register/StudentViewController.swift | 89 +++++++++ Register/ViewController.swift | 20 --- RegisterTests/RegisterTests.swift | 2 +- RegisterUITests/RegisterUITests.swift | 18 +- 16 files changed, 647 insertions(+), 42 deletions(-) create mode 100644 Register.xcodeproj/xcshareddata/xcschemes/Register.xcscheme create mode 100755 Register/AESCrypt/AESCrypt-Bridging-Header.h create mode 100755 Register/AESCrypt/AESCrypt.swift create mode 100644 Register/CoreData/DataManager.swift create mode 100644 Register/CoreData/Register.xcdatamodeld/Register.xcdatamodel/contents delete mode 100644 Register/Register.xcdatamodeld/Register.xcdatamodel/contents create mode 100644 Register/StudentTableViewCell.swift create mode 100644 Register/StudentViewController.swift delete mode 100644 Register/ViewController.swift diff --git a/Register.xcodeproj/project.pbxproj b/Register.xcodeproj/project.pbxproj index 6a6d94e..6d2009e 100644 --- a/Register.xcodeproj/project.pbxproj +++ b/Register.xcodeproj/project.pbxproj @@ -9,13 +9,16 @@ /* Begin PBXBuildFile section */ BC10A63523B74EA4000F519B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A63423B74EA4000F519B /* AppDelegate.swift */; }; BC10A63723B74EA4000F519B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A63623B74EA4000F519B /* SceneDelegate.swift */; }; - BC10A63923B74EA4000F519B /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A63823B74EA4000F519B /* ViewController.swift */; }; + BC10A63923B74EA4000F519B /* StudentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A63823B74EA4000F519B /* StudentViewController.swift */; }; BC10A63C23B74EA4000F519B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BC10A63A23B74EA4000F519B /* Main.storyboard */; }; BC10A63F23B74EA4000F519B /* Register.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BC10A63D23B74EA4000F519B /* Register.xcdatamodeld */; }; BC10A64123B74EA5000F519B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BC10A64023B74EA5000F519B /* Assets.xcassets */; }; BC10A64423B74EA5000F519B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BC10A64223B74EA5000F519B /* LaunchScreen.storyboard */; }; BC10A64F23B74EA5000F519B /* RegisterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A64E23B74EA5000F519B /* RegisterTests.swift */; }; BC10A65A23B74EA5000F519B /* RegisterUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A65923B74EA5000F519B /* RegisterUITests.swift */; }; + BC10A66823B7591D000F519B /* StudentTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A66723B7591D000F519B /* StudentTableViewCell.swift */; }; + BC10A66A23B764DB000F519B /* DataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A66923B764DB000F519B /* DataManager.swift */; }; + BC10A66C23B77E2E000F519B /* AESCrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC10A66B23B77E2E000F519B /* AESCrypt.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -39,7 +42,7 @@ BC10A63123B74EA4000F519B /* Register.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Register.app; sourceTree = BUILT_PRODUCTS_DIR; }; BC10A63423B74EA4000F519B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; BC10A63623B74EA4000F519B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - BC10A63823B74EA4000F519B /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + BC10A63823B74EA4000F519B /* StudentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudentViewController.swift; sourceTree = ""; }; BC10A63B23B74EA4000F519B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; BC10A63E23B74EA4000F519B /* Register.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Register.xcdatamodel; sourceTree = ""; }; BC10A64023B74EA5000F519B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -51,6 +54,10 @@ BC10A65523B74EA5000F519B /* RegisterUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RegisterUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; BC10A65923B74EA5000F519B /* RegisterUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterUITests.swift; sourceTree = ""; }; BC10A65B23B74EA5000F519B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BC10A66723B7591D000F519B /* StudentTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudentTableViewCell.swift; sourceTree = ""; }; + BC10A66923B764DB000F519B /* DataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataManager.swift; sourceTree = ""; }; + BC10A66B23B77E2E000F519B /* AESCrypt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AESCrypt.swift; sourceTree = ""; }; + BC10A66D23B77E86000F519B /* AESCrypt-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AESCrypt-Bridging-Header.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -101,14 +108,16 @@ BC10A63323B74EA4000F519B /* Register */ = { isa = PBXGroup; children = ( + BC10A67023B785D6000F519B /* CoreData */, + BC10A66F23B78215000F519B /* AESCrypt */, BC10A63423B74EA4000F519B /* AppDelegate.swift */, BC10A63623B74EA4000F519B /* SceneDelegate.swift */, - BC10A63823B74EA4000F519B /* ViewController.swift */, + BC10A63823B74EA4000F519B /* StudentViewController.swift */, + BC10A66723B7591D000F519B /* StudentTableViewCell.swift */, BC10A63A23B74EA4000F519B /* Main.storyboard */, BC10A64023B74EA5000F519B /* Assets.xcassets */, BC10A64223B74EA5000F519B /* LaunchScreen.storyboard */, BC10A64523B74EA5000F519B /* Info.plist */, - BC10A63D23B74EA4000F519B /* Register.xcdatamodeld */, ); path = Register; sourceTree = ""; @@ -131,6 +140,24 @@ path = RegisterUITests; sourceTree = ""; }; + BC10A66F23B78215000F519B /* AESCrypt */ = { + isa = PBXGroup; + children = ( + BC10A66B23B77E2E000F519B /* AESCrypt.swift */, + BC10A66D23B77E86000F519B /* AESCrypt-Bridging-Header.h */, + ); + path = AESCrypt; + sourceTree = ""; + }; + BC10A67023B785D6000F519B /* CoreData */ = { + isa = PBXGroup; + children = ( + BC10A66923B764DB000F519B /* DataManager.swift */, + BC10A63D23B74EA4000F519B /* Register.xcdatamodeld */, + ); + path = CoreData; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -262,10 +289,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BC10A63923B74EA4000F519B /* ViewController.swift in Sources */, + BC10A63923B74EA4000F519B /* StudentViewController.swift in Sources */, + BC10A66A23B764DB000F519B /* DataManager.swift in Sources */, + BC10A66823B7591D000F519B /* StudentTableViewCell.swift in Sources */, BC10A63523B74EA4000F519B /* AppDelegate.swift in Sources */, BC10A63F23B74EA4000F519B /* Register.xcdatamodeld in Sources */, BC10A63723B74EA4000F519B /* SceneDelegate.swift in Sources */, + BC10A66C23B77E2E000F519B /* AESCrypt.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -446,6 +476,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.Register; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Register/AESCrypt/AESCrypt-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -463,6 +494,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.Register; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Register/AESCrypt/AESCrypt-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/Register.xcodeproj/xcshareddata/xcschemes/Register.xcscheme b/Register.xcodeproj/xcshareddata/xcschemes/Register.xcscheme new file mode 100644 index 0000000..17847f4 --- /dev/null +++ b/Register.xcodeproj/xcshareddata/xcschemes/Register.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Register.xcodeproj/xcuserdata/admin2.xcuserdatad/xcschemes/xcschememanagement.plist b/Register.xcodeproj/xcuserdata/admin2.xcuserdatad/xcschemes/xcschememanagement.plist index 81835d3..e8c9422 100644 --- a/Register.xcodeproj/xcuserdata/admin2.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Register.xcodeproj/xcuserdata/admin2.xcuserdatad/xcschemes/xcschememanagement.plist @@ -6,9 +6,29 @@ Register.xcscheme_^#shared#^_ + isShown + orderHint 0 + SuppressBuildableAutocreation + + BC10A63023B74EA4000F519B + + primary + + + BC10A64923B74EA5000F519B + + primary + + + BC10A65423B74EA5000F519B + + primary + + + diff --git a/Register/AESCrypt/AESCrypt-Bridging-Header.h b/Register/AESCrypt/AESCrypt-Bridging-Header.h new file mode 100755 index 0000000..9d41e65 --- /dev/null +++ b/Register/AESCrypt/AESCrypt-Bridging-Header.h @@ -0,0 +1,6 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import +#import diff --git a/Register/AESCrypt/AESCrypt.swift b/Register/AESCrypt/AESCrypt.swift new file mode 100755 index 0000000..b92c863 --- /dev/null +++ b/Register/AESCrypt/AESCrypt.swift @@ -0,0 +1,169 @@ +// +// AESCrypt.swift +// AESCryptDemo +// +// Created by Nithin on 8/25/18. +// Copyright © 2018 Apple INC. All rights reserved. +// + +import UIKit + +let PASSWORD = "Swift$" + +class AESCrypt { + + class func AESStringEncryption(message: String?) -> String? { + + guard let messageData = message?.data(using: .utf8), + let keyData = PASSWORD.data(using: .utf8), + let cryptData = NSMutableData(length: messageData.count + kCCBlockSizeAES128) + else { + print("Trying to Encrypt either nil message or password") + return nil + } + + let keyLength = size_t(kCCKeySizeAES128) + let operation = UInt32(kCCEncrypt) + let algoritm = UInt32(kCCAlgorithmAES128) + let options = UInt32(kCCOptionPKCS7Padding) + var numBytesEncrypted :size_t = 0 + + let cryptStatus = CCCrypt(operation, + algoritm, + options, + (keyData as NSData).bytes, keyLength, + nil, + (messageData as NSData).bytes, messageData.count, + cryptData.mutableBytes, cryptData.length, + &numBytesEncrypted) + + if cryptStatus == kCCSuccess { + + cryptData.length = Int(numBytesEncrypted) + let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters) + + return base64cryptString + + } + + print("Failed to Encrypt message and password") + return nil + } + + class func AESStringDecryption(message: String?) -> String? { + + guard let message = message, + let messageData = NSData(base64Encoded: message, options: .ignoreUnknownCharacters), + let keyData = PASSWORD.data(using: .utf8), + let cryptData = NSMutableData(length: messageData.length + kCCBlockSizeAES128) + else { + print("Trying to Decrypt either nil message or password") + return nil + } + + let keyLength = size_t(kCCKeySizeAES128) + let operation = UInt32(kCCDecrypt) + let algoritm = UInt32(kCCAlgorithmAES128) + let options = UInt32(kCCOptionPKCS7Padding) + var numBytesEncrypted :size_t = 0 + + let cryptStatus = CCCrypt(operation, + algoritm, + options, + (keyData as NSData).bytes, keyLength, + nil, + messageData.bytes, messageData.length, + cryptData.mutableBytes, cryptData.length, + &numBytesEncrypted) + + if cryptStatus == kCCSuccess { + + cryptData.length = Int(numBytesEncrypted) + + if let unencryptedMessage = String(data: cryptData as Data, encoding:.utf8) { + + return unencryptedMessage + } + } + + print("Failed to Decrypt message and password") + return nil + } + + class func AESImageEncryption(image: UIImage?) -> NSData? { + + guard let image = image, let imageData = image.pngData(), + let keyData = PASSWORD.data(using: .utf8), + let cryptData = NSMutableData(length: imageData.count + kCCBlockSizeAES128) + else { + print("Trying to Encrypt either nil image or password") + return nil + } + + let keyLength = size_t(kCCKeySizeAES128) + let operation = UInt32(kCCEncrypt) + let algoritm = UInt32(kCCAlgorithmAES128) + let options = UInt32(kCCOptionPKCS7Padding) + var numBytesEncrypted :size_t = 0 + + let cryptStatus = CCCrypt(operation, + algoritm, + options, + (keyData as NSData).bytes, keyLength, + nil, + (imageData as NSData).bytes, (imageData as NSData).length, + cryptData.mutableBytes, cryptData.length, + &numBytesEncrypted) + + if cryptStatus == kCCSuccess { + + cryptData.length = Int(numBytesEncrypted) + let image = cryptData.base64EncodedData(options: .lineLength64Characters) + + return image as NSData + } + + print("Failed to Encrypt image and password") + return nil + } + + class func AESImageDecryption(data: NSData?) -> UIImage? { + + guard let data = data, + let encodedData = NSData(base64Encoded: data as Data, options: .ignoreUnknownCharacters), + let keyData = PASSWORD.data(using: .utf8), + let cryptData = NSMutableData(length: encodedData.length + kCCBlockSizeAES128) + else { + print("Trying to Decrypt either nil image or password") + return nil + } + + let keyLength = size_t(kCCKeySizeAES128) + let operation = UInt32(kCCDecrypt) + let algoritm = UInt32(kCCAlgorithmAES128) + let options = UInt32(kCCOptionPKCS7Padding) + var numBytesEncrypted :size_t = 0 + + let cryptStatus = CCCrypt(operation, + algoritm, + options, + (keyData as NSData).bytes, keyLength, + nil, encodedData.bytes, encodedData.length, + cryptData.mutableBytes, cryptData.length, + &numBytesEncrypted) + + if cryptStatus == kCCSuccess { + + cryptData.length = numBytesEncrypted + + if let image = UIImage(data: cryptData as Data) { + + return image + } + } + + print("Failed to Decrypt image and password") + return nil + } +} + diff --git a/Register/AppDelegate.swift b/Register/AppDelegate.swift index 6500b1a..23cf52f 100644 --- a/Register/AppDelegate.swift +++ b/Register/AppDelegate.swift @@ -2,7 +2,7 @@ // AppDelegate.swift // Register // -// Created by admin2 on 28/12/19. +// Created by Nithin on 28/12/19. // Copyright © 2019 Nithin. All rights reserved. // @@ -16,6 +16,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. + + let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) + print(paths[0]) + return true } diff --git a/Register/Base.lproj/Main.storyboard b/Register/Base.lproj/Main.storyboard index 25a7638..f8a5cc3 100644 --- a/Register/Base.lproj/Main.storyboard +++ b/Register/Base.lproj/Main.storyboard @@ -1,24 +1,134 @@ - + + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Register/CoreData/DataManager.swift b/Register/CoreData/DataManager.swift new file mode 100644 index 0000000..4427487 --- /dev/null +++ b/Register/CoreData/DataManager.swift @@ -0,0 +1,52 @@ +// +// DataManager.swift +// Register +// +// Created by Nithin on 28/12/19. +// Copyright © 2019 Nithin. All rights reserved. +// + +import CoreData +import UIKit + +class DataManager { + + static let `default` = DataManager() + + func save(_ name: String, _ course: String, _ age: String) { + + guard let delegate = UIApplication.shared.delegate as? AppDelegate else { return } + + let context = delegate.persistentContainer.viewContext + + if let entity = NSEntityDescription.entity(forEntityName: "Students", in: context) { + let student = NSManagedObject(entity: entity, insertInto: context) + student.setValue(AESCrypt.AESStringEncryption(message: name), forKey: "name") + student.setValue(AESCrypt.AESStringEncryption(message: course), forKey: "course") + student.setValue(AESCrypt.AESStringEncryption(message: age), forKey: "age") + + do { + + try context.save() + } catch { + print("\(error.localizedDescription)") + } + } + } + + func fetch(completion: (([NSManagedObject]) -> Void)) { + + guard let delegate = UIApplication.shared.delegate as? AppDelegate else { return } + + let context = delegate.persistentContainer.viewContext + + let fetchedStudents = NSFetchRequest(entityName: "Students") + + do { + let students = try context.fetch(fetchedStudents) + completion(students) + } catch { + print("\(error.localizedDescription)") + } + } +} diff --git a/Register/CoreData/Register.xcdatamodeld/Register.xcdatamodel/contents b/Register/CoreData/Register.xcdatamodeld/Register.xcdatamodel/contents new file mode 100644 index 0000000..dfce451 --- /dev/null +++ b/Register/CoreData/Register.xcdatamodeld/Register.xcdatamodel/contents @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Register/Register.xcdatamodeld/Register.xcdatamodel/contents b/Register/Register.xcdatamodeld/Register.xcdatamodel/contents deleted file mode 100644 index 50d2514..0000000 --- a/Register/Register.xcdatamodeld/Register.xcdatamodel/contents +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Register/SceneDelegate.swift b/Register/SceneDelegate.swift index 3d50c10..84fb22e 100644 --- a/Register/SceneDelegate.swift +++ b/Register/SceneDelegate.swift @@ -2,7 +2,7 @@ // SceneDelegate.swift // Register // -// Created by admin2 on 28/12/19. +// Created by Nithin on 28/12/19. // Copyright © 2019 Nithin. All rights reserved. // diff --git a/Register/StudentTableViewCell.swift b/Register/StudentTableViewCell.swift new file mode 100644 index 0000000..78cc4de --- /dev/null +++ b/Register/StudentTableViewCell.swift @@ -0,0 +1,28 @@ +// +// StudentTableViewCell.swift +// Register +// +// Created by Nithin on 28/12/19. +// Copyright © 2019 Nithin. All rights reserved. +// + +import UIKit + +class StudentTableViewCell: UITableViewCell { + + @IBOutlet weak var name: UILabel! + @IBOutlet weak var course: UILabel! + @IBOutlet weak var age: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/Register/StudentViewController.swift b/Register/StudentViewController.swift new file mode 100644 index 0000000..6988287 --- /dev/null +++ b/Register/StudentViewController.swift @@ -0,0 +1,89 @@ +// +// ViewController.swift +// Register +// +// Created by Nithin on 28/12/19. +// Copyright © 2019 Nithin. All rights reserved. +// + +import UIKit +import CoreData + +class StudentViewController: UIViewController { + + @IBOutlet weak var studentTableView: UITableView! + @IBOutlet weak var addNewStudent: UIBarButtonItem! + @IBOutlet weak var noDataLabel: UILabel! + + var students = [NSManagedObject]() + + override func viewDidLoad() { + super.viewDidLoad() + + studentTableView.tableFooterView = UIView(frame: .zero) + reloadData() + } + + @IBAction func addNewStudent(_ sender: Any) { + addNewStudents() + } + + func addNewStudents() { + + let alert = UIAlertController(title: "Add New Student", message: "", preferredStyle: .alert) + + alert.addTextField { (textField) in + textField.placeholder = "Name" + } + + alert.addTextField { (textField) in + textField.placeholder = "Course" + } + + alert.addTextField { (textField) in + textField.placeholder = "Age" + } + + alert.addAction(UIAlertAction(title: "Save", style: .default, handler: { [weak alert,self] (_) in + if let name = alert?.textFields?[0].text, name.isEmpty == false, let course = alert?.textFields?[1].text, course.isEmpty == false, let age = alert?.textFields?[2].text, age.isEmpty == false { + + DataManager.default.save(name.capitalized, course.capitalized, age) + self.reloadData() + } + })) + + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + + self.present(alert, animated: true, completion: nil) + } + + private func reloadData() { + DataManager.default.fetch(completion: { [weak self](students) in + + if students.count > 0 { + self?.students = students + noDataLabel.isHidden = true + studentTableView.reloadData() + } + }) + } +} + +extension StudentViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return students.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? StudentTableViewCell + let student = students[indexPath.row] + + cell?.name.text = AESCrypt.AESStringDecryption(message: student.value(forKey: "name") as? String) + cell?.course.text = AESCrypt.AESStringDecryption(message: student.value(forKey: "course") as? String) + cell?.age.text = AESCrypt.AESStringDecryption(message: student.value(forKey: "age") as? String) + + return cell ?? UITableViewCell() + } +} diff --git a/Register/ViewController.swift b/Register/ViewController.swift deleted file mode 100644 index 42f75cc..0000000 --- a/Register/ViewController.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// ViewController.swift -// Register -// -// Created by admin2 on 28/12/19. -// Copyright © 2019 Nithin. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/RegisterTests/RegisterTests.swift b/RegisterTests/RegisterTests.swift index dd94934..27817b0 100644 --- a/RegisterTests/RegisterTests.swift +++ b/RegisterTests/RegisterTests.swift @@ -2,7 +2,7 @@ // RegisterTests.swift // RegisterTests // -// Created by admin2 on 28/12/19. +// Created by Nithin on 28/12/19. // Copyright © 2019 Nithin. All rights reserved. // diff --git a/RegisterUITests/RegisterUITests.swift b/RegisterUITests/RegisterUITests.swift index 2e70110..e01dcda 100644 --- a/RegisterUITests/RegisterUITests.swift +++ b/RegisterUITests/RegisterUITests.swift @@ -2,7 +2,7 @@ // RegisterUITests.swift // RegisterUITests // -// Created by admin2 on 28/12/19. +// Created by Nithin on 28/12/19. // Copyright © 2019 Nithin. All rights reserved. // @@ -27,9 +27,19 @@ class RegisterUITests: XCTestCase { // UI tests must launch the application that they test. let app = XCUIApplication() app.launch() - - // Use recording to get started writing UI tests. - // Use XCTAssert and related functions to verify your tests produce the correct results. + + app.navigationBars["Music Students"].buttons["plus"].tap() + + let elementsQuery = app.alerts["Add New Student"].scrollViews.otherElements + let collectionViewsQuery = elementsQuery.collectionViews + let nameTextField = collectionViewsQuery.textFields["Name"] + nameTextField.tap() + let courseTextField = collectionViewsQuery/*@START_MENU_TOKEN@*/.textFields["Course"]/*[[".cells.textFields[\"Course\"]",".textFields[\"Course\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/ + courseTextField.tap() + let ageTextField = collectionViewsQuery/*@START_MENU_TOKEN@*/.textFields["Age"]/*[[".cells.textFields[\"Age\"]",".textFields[\"Age\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/ + ageTextField.tap() + + elementsQuery.buttons["Save"].tap() } func testLaunchPerformance() { From 825faf2ffbe718ec836215c92d90a26dbf975e3d Mon Sep 17 00:00:00 2001 From: NithinBabu Date: Fri, 17 Jan 2020 22:30:55 +0530 Subject: [PATCH 2/2] Set up CI with Azure Pipelines [skip ci] --- azure-pipelines.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..925a365 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,20 @@ +# Xcode +# Build, test, and archive an Xcode workspace on macOS. +# Add steps that install certificates, test, sign, and distribute an app, save build artifacts, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/xcode + +trigger: +- master + +pool: + vmImage: 'macos-latest' + +steps: +- task: Xcode@5 + inputs: + actions: 'build' + scheme: '' + sdk: 'iphoneos' + configuration: 'Release' + xcWorkspacePath: '**/*.xcodeproj/project.xcworkspace' + xcodeVersion: 'default' # Options: 8, 9, 10, default, specifyPath