-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from boostcamp-2020/develop
2주차 코드 프리징
- Loading branch information
Showing
32 changed files
with
73,812 additions
and
154 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
disabled_rules: | ||
- trailing_whitespace | ||
- todo | ||
- shorthand_operator | ||
|
||
included: | ||
|
||
|
158 changes: 142 additions & 16 deletions
158
BoostClusteringMaB/BoostClusteringMaB.xcodeproj/project.pbxproj
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
...aB/BoostClusteringMaB.xcworkspace/xcshareddata/xcschemes/BoostClusteringMaBTests.xcscheme
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Scheme | ||
LastUpgradeVersion = "1220" | ||
version = "1.3"> | ||
<BuildAction | ||
parallelizeBuildables = "YES" | ||
buildImplicitDependencies = "YES"> | ||
</BuildAction> | ||
<TestAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
shouldUseLaunchSchemeArgsEnv = "YES"> | ||
<Testables> | ||
<TestableReference | ||
skipped = "NO"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "700A666F25626CF800184916" | ||
BuildableName = "BoostClusteringMaBTests.xctest" | ||
BlueprintName = "BoostClusteringMaBTests" | ||
ReferencedContainer = "container:BoostClusteringMaB.xcodeproj"> | ||
</BuildableReference> | ||
</TestableReference> | ||
</Testables> | ||
</TestAction> | ||
<LaunchAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
launchStyle = "0" | ||
useCustomWorkingDirectory = "NO" | ||
ignoresPersistentStateOnLaunch = "NO" | ||
debugDocumentVersioning = "YES" | ||
debugServiceExtension = "internal" | ||
allowLocationSimulation = "YES"> | ||
</LaunchAction> | ||
<ProfileAction | ||
buildConfiguration = "Release" | ||
shouldUseLaunchSchemeArgsEnv = "YES" | ||
savedToolIdentifier = "" | ||
useCustomWorkingDirectory = "NO" | ||
debugDocumentVersioning = "YES"> | ||
</ProfileAction> | ||
<AnalyzeAction | ||
buildConfiguration = "Debug"> | ||
</AnalyzeAction> | ||
<ArchiveAction | ||
buildConfiguration = "Release" | ||
revealArchiveInOrganizer = "YES"> | ||
</ArchiveAction> | ||
</Scheme> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 12 additions & 2 deletions
14
...oostClusteringMaB/BoostClusteringMaB.xcdatamodeld/BoostClusteringMaB.xcdatamodel/contents
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,14 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="false" userDefinedModelVersionIdentifier=""> | ||
<elements/> | ||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17511" systemVersion="20B29" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> | ||
<entity name="POI" representedClassName="POI" syncable="YES" codeGenerationType="class"> | ||
<attribute name="category" optional="YES" attributeType="String"/> | ||
<attribute name="id" optional="YES" attributeType="String"/> | ||
<attribute name="imageURL" optional="YES" attributeType="String"/> | ||
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/> | ||
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/> | ||
<attribute name="name" optional="YES" attributeType="String"/> | ||
</entity> | ||
<elements> | ||
<element name="POI" positionX="-63" positionY="-18" width="128" height="119"/> | ||
</elements> | ||
</model> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// | ||
// CSVParser.swift | ||
// BoostClusteringMaB | ||
// | ||
// Created by ParkJaeHyun on 2020/11/24. | ||
// | ||
|
||
import Foundation | ||
|
||
class CSVParser { | ||
enum CSVParSerError: Error { | ||
case empty | ||
case invalidFileName | ||
case invalidCSVForm | ||
} | ||
|
||
var pois = [Place]() | ||
|
||
func convertCSVIntoArray(file name: String) throws { | ||
guard let filepath = Bundle.main.path(forResource: name, ofType: "csv"), | ||
let data = try? String(contentsOfFile: filepath) else { | ||
throw CSVParSerError.invalidFileName | ||
} | ||
|
||
var rows = data.components(separatedBy: "\n") | ||
|
||
rows.removeFirst() | ||
|
||
for row in rows { | ||
let columns = row.components(separatedBy: ",") | ||
|
||
if columns.count == 6 { | ||
let id = columns[0] | ||
let name = columns[1] | ||
let category = columns[2] | ||
let x = columns[3] | ||
let y = columns[4] | ||
let imageURL = columns[5] | ||
|
||
let place = Place(id: id, name: name, x: x, y: y, imageURL: imageURL, category: category) | ||
pois.append(place) | ||
} else { | ||
throw CSVParSerError.invalidCSVForm | ||
} | ||
} | ||
} | ||
|
||
func add(to coreDataManager: CoreDataManager) throws { | ||
guard !pois.isEmpty else { | ||
throw CSVParSerError.empty | ||
} | ||
|
||
try pois.forEach({ place in | ||
try coreDataManager.add(place: place, completion: nil) | ||
}) | ||
|
||
try coreDataManager.save() | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
BoostClusteringMaB/BoostClusteringMaB/CoreData/CoreDataContainer.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// CoreDataContainer.swift | ||
// BoostClusteringMaB | ||
// | ||
// Created by 현기엽 on 2020/11/23. | ||
// | ||
|
||
import CoreData | ||
|
||
final class CoreDataContainer { | ||
static var shared: CoreDataContainer = CoreDataContainer() | ||
private let containerName = "BoostClusteringMaB" | ||
|
||
var mainContext: NSManagedObjectContext { | ||
return persistentContainer.viewContext | ||
} | ||
|
||
// MARK: - Core Data stack | ||
private lazy var persistentContainer: NSPersistentContainer = { | ||
let container = NSPersistentContainer(name: containerName) | ||
container.loadPersistentStores(completionHandler: { (_, error) in | ||
if let error = error as NSError? { | ||
fatalError("Unresolved error \(error), \(error.userInfo)") | ||
} | ||
}) | ||
return container | ||
}() | ||
|
||
// MARK: - Core Data Saving support | ||
func saveContext() { | ||
let context = persistentContainer.viewContext | ||
do { | ||
try context.save() | ||
} catch { | ||
let nserror = error as NSError | ||
fatalError("Unresolved error \(nserror), \(nserror.userInfo)") | ||
} | ||
} | ||
} |
111 changes: 111 additions & 0 deletions
111
BoostClusteringMaB/BoostClusteringMaB/CoreData/CoreDataLayer.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// | ||
// CoreDataLayer.swift | ||
// BoostClusteringMaB | ||
// | ||
// Created by 현기엽 on 2020/11/23. | ||
// | ||
|
||
import CoreData | ||
|
||
protocol CoreDataManager { | ||
func add(place: Place, completion handler: (() -> Void)?) throws | ||
func fetch(sorted: Bool) throws -> [POI] | ||
func fetch(by classification: String, sorted: Bool) throws -> [POI] | ||
func fetch(southWest: LatLng, northEast: LatLng, sorted: Bool) throws -> [POI] | ||
func remove(poi: POI) throws | ||
func removeAll() throws | ||
func save() throws | ||
} | ||
|
||
final class CoreDataLayer: CoreDataManager { | ||
enum CoreDataError: Error { | ||
case invalidCoordinate | ||
case saveError(String) | ||
} | ||
|
||
private lazy var childContext: NSManagedObjectContext = { | ||
let childContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) | ||
|
||
childContext.parent = CoreDataContainer.shared.mainContext | ||
return childContext | ||
}() | ||
|
||
func add(place: Place, completion handler: (() -> Void)? = nil) throws { | ||
guard let latitude = Double(place.y), | ||
let longitude = Double(place.x) else { | ||
throw CoreDataError.invalidCoordinate | ||
} | ||
|
||
childContext.perform { [weak self] in | ||
guard let self = self else { | ||
return | ||
} | ||
let poi = POI(context: self.childContext) | ||
poi.id = place.id | ||
poi.category = place.category | ||
poi.imageURL = place.imageURL | ||
poi.latitude = latitude | ||
poi.longitude = longitude | ||
poi.name = place.name | ||
handler?() | ||
} | ||
} | ||
|
||
func fetch(sorted: Bool = true) throws -> [POI] { | ||
let request: NSFetchRequest = POI.fetchRequest() | ||
request.sortDescriptors = makeSortDescription(sorted: sorted) | ||
|
||
return try childContext.fetch(request) | ||
} | ||
|
||
func fetch(by classification: String, sorted: Bool = true) throws -> [POI] { | ||
let request: NSFetchRequest = POI.fetchRequest() | ||
request.predicate = NSPredicate(format: "category == %@", classification) | ||
request.sortDescriptors = makeSortDescription(sorted: sorted) | ||
|
||
let pois = try childContext.fetch(request) | ||
|
||
return pois | ||
} | ||
|
||
func fetch(southWest: LatLng, northEast: LatLng, sorted: Bool = true) throws -> [POI] { | ||
guard northEast.lat > southWest.lat, | ||
northEast.lng > southWest.lng else { | ||
throw CoreDataError.invalidCoordinate | ||
} | ||
|
||
let latitudePredicate = NSPredicate(format: "latitude BETWEEN {%@, %@}", | ||
argumentArray: [southWest.lat, northEast.lat]) | ||
let longitudePredicate = NSPredicate(format: "longitude BETWEEN {%@, %@}", | ||
argumentArray: [southWest.lng, northEast.lng]) | ||
let predicate = NSCompoundPredicate(type: .and, subpredicates: [latitudePredicate, longitudePredicate]) | ||
|
||
let request: NSFetchRequest = POI.fetchRequest() | ||
request.predicate = predicate | ||
request.sortDescriptors = makeSortDescription(sorted: sorted) | ||
|
||
return try childContext.fetch(request) | ||
} | ||
|
||
private func makeSortDescription(sorted: Bool) -> [NSSortDescriptor]? { | ||
let latitudeSort = NSSortDescriptor(key: "latitude", ascending: true) | ||
let longitudeSort = NSSortDescriptor(key: "longitude", ascending: true) | ||
|
||
return sorted ? [latitudeSort, longitudeSort] : nil | ||
} | ||
|
||
func remove(poi: POI) { | ||
childContext.delete(poi) | ||
} | ||
|
||
func removeAll() throws { | ||
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "POI") | ||
let removeAll = NSBatchDeleteRequest(fetchRequest: request) | ||
try childContext.execute(removeAll) | ||
} | ||
|
||
func save() throws { | ||
try childContext.save() | ||
CoreDataContainer.shared.saveContext() | ||
} | ||
} |
Oops, something went wrong.