Archived
SQLite implementation of substitution plan persistence added, working in simulator, untested on real devices
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import CoreData
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
@@ -39,8 +40,60 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
self.saveContext()
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Core Data stack
|
||||
|
||||
lazy var persistentContainer: NSPersistentContainer = {
|
||||
/*
|
||||
The persistent container for the application. This implementation
|
||||
creates and returns a container, having loaded the store for the
|
||||
application to it. This property is optional since there are legitimate
|
||||
error conditions that could cause the creation of the store to fail.
|
||||
*/
|
||||
let container = NSPersistentContainer(name: "Model")
|
||||
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
|
||||
if let error = error as NSError? {
|
||||
// Replace this implementation with code to handle the error appropriately.
|
||||
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||||
|
||||
/*
|
||||
Typical reasons for an error here include:
|
||||
* The parent directory does not exist, cannot be created, or disallows writing.
|
||||
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
|
||||
* The device is out of space.
|
||||
* The store could not be migrated to the current model version.
|
||||
Check the error message to determine what the actual problem was.
|
||||
*/
|
||||
fatalError("Unresolved error \(error), \(error.userInfo)")
|
||||
}
|
||||
})
|
||||
return container
|
||||
}()
|
||||
|
||||
// MARK: - Core Data Saving support
|
||||
|
||||
func saveContext () {
|
||||
let context = persistentContainer.viewContext
|
||||
if context.hasChanges {
|
||||
do {
|
||||
try context.save()
|
||||
} catch {
|
||||
// Replace this implementation with code to handle the error appropriately.
|
||||
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||||
let nserror = error as NSError
|
||||
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static var persistentContainer: NSPersistentContainer {
|
||||
return (UIApplication.shared.delegate as! AppDelegate).persistentContainer
|
||||
}
|
||||
|
||||
static var viewContext: NSManagedObjectContext {
|
||||
return persistentContainer.viewContext
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,24 @@
|
||||
// Copyright © 2019 Deniz Duezgoeren. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Alamofire
|
||||
import SwiftSoup
|
||||
import SQLite
|
||||
|
||||
class DataFetcher {
|
||||
|
||||
let path = Bundle.main.path(forResource: "db", ofType: "sqlite3")
|
||||
|
||||
let substitutions = Table("substitutions")
|
||||
let id = Expression<Int64>("id")
|
||||
let group = Expression<String>("group")
|
||||
let course = Expression<String>("course")
|
||||
let additional = Expression<String>("additional")
|
||||
let date = Expression<String>("date")
|
||||
let time = Expression<String>("time")
|
||||
let room = Expression<String>("room")
|
||||
|
||||
func doAsync(completionHandler: @escaping (_ substitutions: Array<SubstModel>) -> ()) {
|
||||
DispatchQueue(label: "work-queue").async {
|
||||
let url = "https://djd4rkn355.github.io/subst_test.html"
|
||||
@@ -31,13 +42,34 @@ class DataFetcher {
|
||||
let doc: Document = try SwiftSoup.parse(html)
|
||||
let rows: Elements = try doc.select("tr")
|
||||
|
||||
let db = try Connection(path!)
|
||||
|
||||
try db.run(substitutions.create { t in
|
||||
t.column(id, primaryKey: true)
|
||||
t.column(group)
|
||||
t.column(course)
|
||||
t.column(additional)
|
||||
t.column(date)
|
||||
t.column(time)
|
||||
t.column(room)
|
||||
})
|
||||
|
||||
for i in (0..<rows.size()) {
|
||||
let row = rows.get(i)
|
||||
let cols = try row.select("th")
|
||||
|
||||
subst.append(SubstModel(group: try cols.get(0).text(), course: try cols.get(3).text(), additional: try cols.get(5).text(),
|
||||
date: try cols.get(1).text(), time: try cols.get(2).text(), room: try cols.get(4).text()))
|
||||
let mGroup = try cols.get(0).text()
|
||||
let mCourse = try cols.get(3).text()
|
||||
let mAdditional = try cols.get(5).text()
|
||||
let mDate = try cols.get(1).text()
|
||||
let mTime = try cols.get(2).text()
|
||||
let mRoom = try cols.get(4).text()
|
||||
|
||||
subst.append(SubstModel(group: mGroup, course: mCourse, additional: mAdditional,
|
||||
date: mDate, time: mTime, room: mRoom))
|
||||
let insert = substitutions.insert(group <- mGroup, course <- mCourse, additional <- mAdditional,
|
||||
date <- mDate, time <- mTime, room <- mRoom)
|
||||
_ = try db.run(insert)
|
||||
}
|
||||
|
||||
} catch Exception.Error(let type, let message) {
|
||||
@@ -49,6 +81,17 @@ class DataFetcher {
|
||||
return subst
|
||||
}
|
||||
|
||||
func getFromDatabase() -> [SubstModel] {
|
||||
var substs = [SubstModel]()
|
||||
do {
|
||||
let db = try Connection(path!)
|
||||
for subst in try db.prepare(substitutions) {
|
||||
substs.append(SubstModel(group: subst[group], course: subst[course], additional: subst[additional], date: subst[date], time: subst[time], room: subst[room]))
|
||||
}
|
||||
} catch {}
|
||||
return substs
|
||||
}
|
||||
|
||||
func getImage(from icon: String) -> UIImage? {
|
||||
var imagePath = ""
|
||||
let i = icon.lowercased()
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14490.98" systemVersion="18D109" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="Meal" representedClassName=".Meal" syncable="YES" codeGenerationType="category">
|
||||
<attribute name="priority" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
|
||||
<attribute name="text" optional="YES" attributeType="String" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="Substitution" representedClassName=".Substitution" syncable="YES" codeGenerationType="category">
|
||||
<attribute name="additional" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="course" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="date" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="group" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="priority" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
|
||||
<attribute name="room" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="String" syncable="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Substitution" positionX="-54" positionY="-9" width="128" height="148"/>
|
||||
<element name="Meal" positionX="176.953125" positionY="26.046875" width="128" height="73"/>
|
||||
</elements>
|
||||
</model>
|
||||
@@ -7,9 +7,6 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SwiftSoup
|
||||
import Alamofire
|
||||
import SQLite3
|
||||
|
||||
class PlanViewController : UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
|
||||
|
||||
@@ -17,7 +14,6 @@ class PlanViewController : UIViewController, UICollectionViewDataSource, UIColle
|
||||
@IBOutlet weak var collectionView: UICollectionView!
|
||||
var substs = Array<SubstModel>()
|
||||
private let refreshControl = UIRefreshControl()
|
||||
var db: OpaquePointer?
|
||||
let df = DataFetcher()
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@@ -43,6 +39,9 @@ class PlanViewController : UIViewController, UICollectionViewDataSource, UIColle
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
collectionView.backgroundColor = UIColor(red: 0.8, green: 0.8, blue: 0.8, alpha: 1.0)
|
||||
|
||||
self.substs = self.df.getFromDatabase()
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
@@ -76,17 +75,14 @@ class PlanViewController : UIViewController, UICollectionViewDataSource, UIColle
|
||||
}
|
||||
}
|
||||
|
||||
// cell.courseIcon.frame = CGRect(x: 0, y: 0, width: cell.course.frame.height, height: cell.course.frame.height)
|
||||
|
||||
// cell.backgroundColor = UIColor(red: 0.39, green: 0.71, blue: 0.96, alpha: 1.0)
|
||||
cell.backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
|
||||
cell.tintView.backgroundColor = cell.backgroundColor
|
||||
return cell
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
print("You selected cell#\(indexPath.item)!")
|
||||
}
|
||||
// func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
// print("You selected cell#\(indexPath.item)!")
|
||||
// }
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
||||
return CGSize(width: view.frame.size.width, height: 108)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14490.98" systemVersion="18D109" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="Entity" representedClassName="Entity" syncable="YES" codeGenerationType="class"/>
|
||||
<elements>
|
||||
<element name="Entity" positionX="-63" positionY="-18" width="128" height="45"/>
|
||||
</elements>
|
||||
</model>
|
||||
Reference in New Issue
Block a user