Skip to content

Commit 033f9bb

Browse files
Add isDone Bool to data model. Rewrite Data Model to use just Core Data, without the unnecessary Dictionary<String, String>
1 parent 1dd55ba commit 033f9bb

12 files changed

+155
-81
lines changed

TaskApplication.xcodeproj/project.pbxproj

+22
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
63D626032219DF46001EA35C /* Task+CoreDataClass.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D626012219DF46001EA35C /* Task+CoreDataClass.m */; };
11+
63D626042219DF46001EA35C /* Task+CoreDataProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D626022219DF46001EA35C /* Task+CoreDataProperties.m */; };
1012
8685C2211A6F503100F5CE9F /* PersistenceHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8685C2201A6F503100F5CE9F /* PersistenceHelper.swift */; };
1113
8685C2261A6F550A00F5CE9F /* TaskApplication.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 8685C2241A6F550A00F5CE9F /* TaskApplication.xcdatamodeld */; };
1214
86FF5BB31A6D65FB00A017A1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86FF5BB21A6D65FB00A017A1 /* AppDelegate.swift */; };
@@ -19,6 +21,11 @@
1921
/* End PBXBuildFile section */
2022

2123
/* Begin PBXFileReference section */
24+
63D625FE2219DF45001EA35C /* TaskApplication-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TaskApplication-Bridging-Header.h"; sourceTree = "<group>"; };
25+
63D625FF2219DF46001EA35C /* Task+CoreDataProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Task+CoreDataProperties.h"; sourceTree = "<group>"; };
26+
63D626002219DF46001EA35C /* Task+CoreDataClass.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Task+CoreDataClass.h"; sourceTree = "<group>"; };
27+
63D626012219DF46001EA35C /* Task+CoreDataClass.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Task+CoreDataClass.m"; sourceTree = "<group>"; };
28+
63D626022219DF46001EA35C /* Task+CoreDataProperties.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Task+CoreDataProperties.m"; sourceTree = "<group>"; };
2229
8685C2201A6F503100F5CE9F /* PersistenceHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersistenceHelper.swift; sourceTree = "<group>"; };
2330
8685C2251A6F550A00F5CE9F /* TaskApplication.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TaskApplication.xcdatamodel; sourceTree = "<group>"; };
2431
86FF5BAD1A6D65FB00A017A1 /* TaskApplication.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TaskApplication.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -79,6 +86,11 @@
7986
86FF5BB01A6D65FB00A017A1 /* Supporting Files */ = {
8087
isa = PBXGroup;
8188
children = (
89+
63D625FE2219DF45001EA35C /* TaskApplication-Bridging-Header.h */,
90+
63D625FF2219DF46001EA35C /* Task+CoreDataProperties.h */,
91+
63D626002219DF46001EA35C /* Task+CoreDataClass.h */,
92+
63D626012219DF46001EA35C /* Task+CoreDataClass.m */,
93+
63D626022219DF46001EA35C /* Task+CoreDataProperties.m */,
8294
86FF5BB11A6D65FB00A017A1 /* Info.plist */,
8395
);
8496
name = "Supporting Files";
@@ -118,6 +130,7 @@
118130
86FF5BAC1A6D65FB00A017A1 = {
119131
CreatedOnToolsVersion = 6.1.1;
120132
DevelopmentTeam = 2X3M9VFULE;
133+
LastSwiftMigration = 1010;
121134
};
122135
};
123136
};
@@ -159,10 +172,12 @@
159172
files = (
160173
86FF5BB71A6D65FB00A017A1 /* SecondViewController.swift in Sources */,
161174
86FF5BB31A6D65FB00A017A1 /* AppDelegate.swift in Sources */,
175+
63D626042219DF46001EA35C /* Task+CoreDataProperties.m in Sources */,
162176
86FF5BD51A6D697400A017A1 /* TaskManager.swift in Sources */,
163177
8685C2211A6F503100F5CE9F /* PersistenceHelper.swift in Sources */,
164178
86FF5BB51A6D65FB00A017A1 /* FirstViewController.swift in Sources */,
165179
8685C2261A6F550A00F5CE9F /* TaskApplication.xcdatamodeld in Sources */,
180+
63D626032219DF46001EA35C /* Task+CoreDataClass.m in Sources */,
166181
);
167182
runOnlyForDeploymentPostprocessing = 0;
168183
};
@@ -273,6 +288,7 @@
273288
buildSettings = {
274289
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
275290
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
291+
CLANG_ENABLE_MODULES = YES;
276292
CODE_SIGN_IDENTITY = "iPhone Developer";
277293
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
278294
DEVELOPMENT_TEAM = 2X3M9VFULE;
@@ -281,6 +297,9 @@
281297
PRODUCT_BUNDLE_IDENTIFIER = "net.michaelcrump.$(PRODUCT_NAME:rfc1034identifier)";
282298
PRODUCT_NAME = "$(TARGET_NAME)";
283299
PROVISIONING_PROFILE = "";
300+
SWIFT_OBJC_BRIDGING_HEADER = "TaskApplication-Bridging-Header.h";
301+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
302+
SWIFT_VERSION = 4.2;
284303
};
285304
name = Debug;
286305
};
@@ -289,6 +308,7 @@
289308
buildSettings = {
290309
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
291310
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
311+
CLANG_ENABLE_MODULES = YES;
292312
CODE_SIGN_IDENTITY = "iPhone Developer";
293313
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
294314
DEVELOPMENT_TEAM = 2X3M9VFULE;
@@ -297,6 +317,8 @@
297317
PRODUCT_BUNDLE_IDENTIFIER = "net.michaelcrump.$(PRODUCT_NAME:rfc1034identifier)";
298318
PRODUCT_NAME = "$(TARGET_NAME)";
299319
PROVISIONING_PROFILE = "";
320+
SWIFT_OBJC_BRIDGING_HEADER = "TaskApplication-Bridging-Header.h";
321+
SWIFT_VERSION = 4.2;
300322
};
301323
name = Release;
302324
};

TaskApplication/AppDelegate.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1616
var window: UIWindow?
1717

1818

19-
private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
19+
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {
2020
// Override point for customization after application launch.
2121
//UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default
2222
return true
2323
}
24+
25+
func applicationWillResignActive(_ application: UIApplication) {
26+
saveContext()
27+
}
2428

2529

2630
// MARK: - Core Data stack

TaskApplication/FirstViewController.swift

+19-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,13 @@ class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDat
4343
let cell: UITableViewCell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "Default Tasks")
4444

4545
//Assign the contents of our var "items" to the textLabel of each cell
46-
let task = taskMgr.tasks[indexPath.row]
47-
cell.textLabel!.text = task.name
48-
cell.detailTextLabel!.text = task.description
46+
let task = taskMgr.tasks[indexPath.row]
47+
let text = NSMutableAttributedString(string: task.name ?? "")
48+
if task.isDone?.boolValue ?? false {
49+
text.addAttribute(.strikethroughStyle, value: 1, range: NSMakeRange(0, text.length))
50+
}
51+
cell.textLabel!.attributedText = text
52+
cell.detailTextLabel!.text = task.desc
4953

5054
return cell
5155

@@ -60,6 +64,18 @@ class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDat
6064
}
6165

6266
}
67+
68+
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
69+
if taskMgr.tasks[indexPath.row].isDone?.boolValue ?? false {
70+
taskMgr.tasks[indexPath.row].isDone = nil
71+
} else {
72+
taskMgr.tasks[indexPath.row].isDone = true
73+
}
74+
75+
tableView.deselectRow(at: indexPath, animated: true)
76+
tableView.reloadRows(at: [indexPath], with: .fade)
77+
}
78+
6379

6480
}
6581

TaskApplication/PersistenceHelper.swift

+26-48
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,32 @@ import CoreData
1212
class PersistenceHelper: NSObject {
1313

1414
var appDel: AppDelegate = (UIApplication.shared.delegate as! AppDelegate)
15-
var context: NSManagedObjectContext;
15+
var context: NSManagedObjectContext;
16+
17+
override init(){
18+
context = appDel.managedObjectContext
19+
}
20+
21+
func construct(entity: String)-> Task? {
22+
return NSEntityDescription.insertNewObject(forEntityName: entity, into: context) as? Task
23+
}
24+
25+
func list(entity: String ) -> [Task] {
1626

17-
override init(){
18-
context = appDel.managedObjectContext
27+
let request = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
28+
request.returnsObjectsAsFaults = false;
29+
let results: [Task] = try! context.fetch(request) as! [Task]
30+
return results
31+
}
32+
33+
func remove(entity:String, instance: NSManagedObject) -> Bool {
34+
context.delete(instance)
35+
do {
36+
try context.save()
37+
} catch _ {
38+
return false
1939
}
20-
21-
func save(entity: String, parameters: Dictionary<String,String> )->Bool{
22-
23-
let newEntity = NSEntityDescription.insertNewObject(forEntityName: entity, into: context)
24-
for (key, value) in parameters{
25-
newEntity.setValue(value, forKey: key)
26-
}
27-
28-
do {
29-
try context.save()
30-
return true
31-
} catch _ {
32-
return false
33-
}
34-
}
35-
36-
func list(entity: String ) ->NSArray{
37-
38-
let request = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
39-
request.returnsObjectsAsFaults = false;
40-
let results: NSArray = try! context.fetch(request) as NSArray
41-
return results
42-
}
43-
44-
func remove(entity:String, key:String, value:String)->Bool{
45-
46-
let request = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
47-
request.returnsObjectsAsFaults = false
48-
request.predicate = NSPredicate(format: "\(key) = %@", value)
49-
let results: NSArray = try! context.fetch(request) as NSArray
50-
51-
if(results.count>0){
52-
53-
let res = results[0] as! NSManagedObject
54-
context.delete(res)
55-
do {
56-
try context.save()
57-
} catch _ {
58-
}
59-
return true
60-
}
61-
62-
return false
63-
}
64-
40+
return true
41+
}
42+
6543
}

TaskApplication/SecondViewController.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class SecondViewController: UIViewController, UITextFieldDelegate {
3232
//add record
3333
let name: String = txtTask.text!
3434
let description: String = txtDesc.text!
35-
taskMgr.addTask(name: name, desc: description)
35+
taskMgr.addTask(name: name, desc: description, isDone: false)
3636

3737
//dismiss keyboard and reset fields
3838

TaskApplication/Task+CoreDataClass.h

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Task+CoreDataClass.h
2+
// Created by David Phillip Oster on 2/17/19.
3+
4+
#import <Foundation/Foundation.h>
5+
#import <CoreData/CoreData.h>
6+
7+
NS_ASSUME_NONNULL_BEGIN
8+
9+
@interface Task : NSManagedObject
10+
11+
@end
12+
13+
NS_ASSUME_NONNULL_END
14+
15+
#import "Task+CoreDataProperties.h"

TaskApplication/Task+CoreDataClass.m

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Task+CoreDataClass.m
2+
// Created by David Phillip Oster on 2/17/19.
3+
4+
#import "Task+CoreDataClass.h"
5+
6+
@implementation Task
7+
8+
@end
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Task+CoreDataProperties.h
2+
// Created by David Phillip Oster on 2/17/19.
3+
4+
#import "Task+CoreDataClass.h"
5+
6+
7+
NS_ASSUME_NONNULL_BEGIN
8+
9+
@interface Task (CoreDataProperties)
10+
11+
+ (NSFetchRequest<Task *> *)fetchRequest;
12+
13+
@property (nullable, nonatomic, copy) NSString *desc;
14+
@property (nullable, nonatomic, copy) NSNumber *isDone;
15+
@property (nullable, nonatomic, copy) NSString *name;
16+
17+
@end
18+
19+
NS_ASSUME_NONNULL_END
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Task+CoreDataProperties.m
2+
// Created by David Phillip Oster on 2/17/19.
3+
4+
#import "Task+CoreDataProperties.h"
5+
6+
@implementation Task (CoreDataProperties)
7+
8+
+ (NSFetchRequest<Task *> *)fetchRequest {
9+
return [NSFetchRequest fetchRequestWithEntityName:@"Task"];
10+
}
11+
12+
@dynamic desc;
13+
@dynamic isDone;
14+
@dynamic name;
15+
16+
@end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Use this file to import your target's public headers that you would like to expose to Swift.
2+
//
3+
4+
#import "Task+CoreDataClass.h"
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6254" systemVersion="14B25" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
3-
<entity name="Task" syncable="YES">
2+
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="18D109" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
3+
<entity name="Task" representedClassName="Task" syncable="YES">
44
<attribute name="desc" optional="YES" attributeType="String" syncable="YES"/>
5+
<attribute name="isDone" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="NO" syncable="YES"/>
56
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
67
</entity>
78
<elements>
8-
<element name="Task" positionX="-63" positionY="-18" width="128" height="75"/>
9+
<element name="Task" positionX="-63" positionY="-18" width="128" height="90"/>
910
</elements>
1011
</model>

TaskApplication/TaskManager.swift

+16-25
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,40 @@
44
//
55
// Created by Michael Crump
66
// Copyright (c) 2015 Michael Crump. All rights reserved.
7-
//
7+
// Changes by David Phillip Oster on 2/17/19.
8+
// Added isDone BOOL here and in data model
9+
// Rewrite Data Model to use just Core Data, without the unnecessary Dictionary<String, String>
810

911
import UIKit
1012

1113
var taskMgr: TaskManager = TaskManager()
1214

13-
struct Task {
14-
var name = "Name"
15-
var description = "Description"
16-
}
17-
1815
class TaskManager: NSObject {
1916

2017
var tasks = [Task]()
2118
var persistenceHelper: PersistenceHelper = PersistenceHelper()
2219

2320
override init(){
2421

25-
let tempTasks:NSArray = persistenceHelper.list(entity: "Task")
26-
for res:Any in tempTasks {
27-
tasks.append(Task(name:(res as AnyObject).value(forKey:"name")as! String,description:(res as AnyObject).value(forKey:"desc") as! String))
28-
}
22+
let tempTasks:[Task] = persistenceHelper.list(entity: "Task")
23+
tasks = tempTasks
2924
}
3025

3126

32-
func addTask(name:String, desc: String){
33-
34-
var dicTask: Dictionary<String, String> = Dictionary<String,String>()
35-
dicTask["name"] = name
36-
dicTask["desc"] = desc
37-
38-
if(persistenceHelper.save(entity: "Task", parameters: dicTask)){
39-
tasks.append(Task(name: name, description:desc))
40-
}
27+
func addTask(name:String, desc: String, isDone: Bool){
28+
if let task = persistenceHelper.construct(entity: "Task") {
29+
task.desc = desc
30+
task.name = name
31+
task.isDone = isDone as NSNumber
32+
tasks.append(task)
33+
}
4134
}
4235

4336
func removeTask(index:Int){
44-
45-
let value:String = tasks[index].name
46-
47-
if(persistenceHelper.remove(entity: "Task", key: "name", value: value)){
48-
tasks.remove(at:index)
49-
}
37+
let task = tasks[index]
38+
if persistenceHelper.remove(entity: "Task", instance: task) {
39+
tasks.remove(at: index)
40+
}
5041
}
5142

5243

0 commit comments

Comments
 (0)