Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.xcuserdatad
12 changes: 6 additions & 6 deletions Moody/Moody.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@
buildSettings = {
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 58PSC9526Y;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
Expand All @@ -1303,7 +1303,7 @@
buildSettings = {
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 58PSC9526Y;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
};
name = Release;
};
Expand Down Expand Up @@ -1398,7 +1398,7 @@
buildSettings = {
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 58PSC9526Y;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
Expand All @@ -1408,7 +1408,7 @@
buildSettings = {
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 58PSC9526Y;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
};
name = Release;
};
Expand Down Expand Up @@ -1442,7 +1442,7 @@
DYLIB_CURRENT_VERSION = 1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
Expand All @@ -1457,7 +1457,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
};
name = Release;
};
Expand Down
2 changes: 1 addition & 1 deletion Moody/MoodyModel/MoodyMergePolicy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ extension NSMergeConflict {
extension Sequence where Iterator.Element == NSMergeConflict {
func conflictedObjects<T>(of cls: T.Type) -> [T] {
let objects = map { $0.sourceObject }
return objects.flatMap { $0 as? T }
return objects.compactMap { $0 as? T }
}

func conflictsAndObjects<T>(of cls: T.Type) -> [(NSMergeConflict, T)] {
Expand Down
6 changes: 3 additions & 3 deletions Moody/MoodySync/ApplicationActiveStateObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protocol ObserverTokenStore : class {
/// This is a helper protocol for the SyncCoordinator.
///
/// It receives application active / background state changes and forwards them after switching onto the right queue.
protocol ApplicationActiveStateObserving : class, ObserverTokenStore {
protocol ApplicationActiveStateObserving : ObserverTokenStore {
/// Runs the given block on the right queue and dispatch group.
func perform(_ block: @escaping () -> ())

Expand All @@ -29,13 +29,13 @@ protocol ApplicationActiveStateObserving : class, ObserverTokenStore {

extension ApplicationActiveStateObserving {
func setupApplicationActiveNotifications() {
addObserverToken(NotificationCenter.default.addObserver(forName: .UIApplicationDidEnterBackground, object: nil, queue: nil) { [weak self] note in
addObserverToken(NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: nil) { [weak self] note in
guard let observer = self else { return }
observer.perform {
observer.applicationDidEnterBackground()
}
})
addObserverToken(NotificationCenter.default.addObserver(forName: .UIApplicationDidBecomeActive, object: nil, queue: nil) { [weak self] note in
addObserverToken(NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { [weak self] note in
guard let observer = self else { return }
observer.perform {
observer.applicationDidBecomeActive()
Expand Down
23 changes: 12 additions & 11 deletions Moody/MoodySync/CloudKit+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ import CloudKit
enum CloudKitRecordChange {
case created(CKRecord)
case updated(CKRecord)
case deleted(CKRecordID)
case deleted(CKRecord.ID)
}


extension CKContainer {

func fetchAllPendingNotifications(changeToken: CKServerChangeToken?, processChanges: @escaping (_ changeReasons: [CKRecordID: CKQueryNotificationReason], _ error: NSError?, _ callback: @escaping (_ success: Bool) -> ()) -> ()) {
func fetchAllPendingNotifications(changeToken: CKServerChangeToken?, processChanges: @escaping (_ changeReasons: [CKRecord.ID: CKQueryNotification.Reason], _ error: NSError?, _ callback: @escaping (_ success: Bool) -> ()) -> ()) {
let op = CKFetchNotificationChangesOperation(previousServerChangeToken: changeToken)
var changeReasons: [CKRecordID: CKQueryNotificationReason] = [:]
var notificationIDs: [CKNotificationID] = []
var changeReasons: [CKRecord.ID: CKQueryNotification.Reason] = [:]
var notificationIDs: [CKNotification.ID] = []
op.notificationChangedBlock = { note in
if let notificationID = note.notificationID {
notificationIDs.append(notificationID)
Expand All @@ -48,9 +48,9 @@ extension CKContainer {

extension CKDatabase {

func fetchRecords(for changeReasons: [CKRecordID: CKQueryNotificationReason], completion: @escaping ([CloudKitRecordChange], NSError?) -> ()) {
var deletedIDs: [CKRecordID] = []
var insertedOrUpdatedIDs: [CKRecordID] = []
func fetchRecords(for changeReasons: [CKRecord.ID: CKQueryNotification.Reason], completion: @escaping ([CloudKitRecordChange], NSError?) -> ()) {
var deletedIDs: [CKRecord.ID] = []
var insertedOrUpdatedIDs: [CKRecord.ID] = []
for (id, reason) in changeReasons {
switch reason {
case .recordDeleted: deletedIDs.append(id)
Expand Down Expand Up @@ -96,15 +96,15 @@ extension CKQueryOperation {

extension NSError {

func partiallyFailedRecords() -> [CKRecordID:NSError] {
func partiallyFailedRecords() -> [CKRecord.ID:NSError] {
guard domain == CKErrorDomain else { return [:] }
let errorCode = CKError.Code(rawValue: code)
guard errorCode == .partialFailure else { return [:] }
return userInfo[CKPartialErrorsByItemIDKey] as? [CKRecordID:NSError] ?? [:]
return userInfo[CKPartialErrorsByItemIDKey] as? [CKRecord.ID:NSError] ?? [:]
}

var partiallyFailedRecordIDsWithPermanentError: [CKRecordID] {
var result: [CKRecordID] = []
var partiallyFailedRecordIDsWithPermanentError: [CKRecord.ID] {
var result: [CKRecord.ID] = []
for (remoteID, partialError) in partiallyFailedRecords() {
if partialError.permanentCloudKitError {
result.append(remoteID)
Expand Down Expand Up @@ -151,6 +151,7 @@ extension NSError {
case .managedAccountRestricted: return true
case .participantMayNeedVerification: return true
case .serverResponseLost: return false
case .assetNotAvailable: return true
}
}
}
Expand Down
22 changes: 9 additions & 13 deletions Moody/MoodySync/CloudKitRemote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ final class CloudKitRemote: MoodyRemote {
func setupMoodSubscription() {
let subscriptionID = "MoodDownload"
let predicate = NSPredicate(format: "TRUEPREDICATE")
let options: CKQuerySubscriptionOptions = [.firesOnRecordCreation, .firesOnRecordUpdate, .firesOnRecordDeletion]
let options: CKQuerySubscription.Options = [.firesOnRecordCreation, .firesOnRecordUpdate, .firesOnRecordDeletion]
let subscription = CKQuerySubscription(recordType: "Mood", predicate: predicate, subscriptionID: subscriptionID, options: options)
let info = CKNotificationInfo()
let info = CKSubscription.NotificationInfo()
info.shouldSendContentAvailable = true
subscription.notificationInfo = info
let op = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: [])
Expand All @@ -36,7 +36,7 @@ final class CloudKitRemote: MoodyRemote {
let op = CKQueryOperation(query: query)
op.resultsLimit = maximumNumberOfMoods
op.fetchAggregateResults(in: cloudKitContainer.publicCloudDatabase, previousResults: []) { records, _ in
completion(records.map { RemoteMood(record: $0) }.flatMap { $0 })
completion(records.map { RemoteMood(record: $0) }.compactMap { $0 })
}
}

Expand All @@ -45,7 +45,7 @@ final class CloudKitRemote: MoodyRemote {
guard error == nil else { return completion([], { _ in }) } // TODO We should handle this case with e.g. a clean refetch
guard changeReasons.count > 0 else { return completion([], callback) }
self.cloudKitContainer.publicCloudDatabase.fetchRecords(for: changeReasons) { changes, error in
completion(changes.map { RemoteRecordChange(moodChange: $0) }.flatMap { $0 }, callback)
completion(changes.map { RemoteRecordChange(moodChange: $0) }.compactMap { $0 }, callback)
}
}
}
Expand All @@ -55,17 +55,17 @@ final class CloudKitRemote: MoodyRemote {
let op = CKModifyRecordsOperation(recordsToSave: recordsToSave,
recordIDsToDelete: nil)
op.modifyRecordsCompletionBlock = { modifiedRecords, _, error in
let remoteMoods = modifiedRecords?.map { RemoteMood(record: $0) }.flatMap { $0 } ?? []
let remoteMoods = modifiedRecords?.map { RemoteMood(record: $0) }.compactMap { $0 } ?? []
let remoteError = RemoteError(cloudKitError: error)
completion(remoteMoods, remoteError)
}
cloudKitContainer.publicCloudDatabase.add(op)
}

func remove(_ moods: [Mood], completion: @escaping ([RemoteRecordID], RemoteError?) -> ()) {
let recordIDsToDelete = moods.map { (mood: Mood) -> CKRecordID in
let recordIDsToDelete = moods.map { (mood: Mood) -> CKRecord.ID in
guard let name = mood.remoteIdentifier else { fatalError("Must have a remote ID") }
return CKRecordID(recordName: name)
return CKRecord.ID(recordName: name)
}
let op = CKModifyRecordsOperation(recordsToSave: nil, recordIDsToDelete: recordIDsToDelete)
op.modifyRecordsCompletionBlock = { _, deletedRecordIDs, error in
Expand Down Expand Up @@ -124,12 +124,8 @@ extension RemoteMood {
else { return nil }
let isoCountry = ISO3166.Country(rawValue: Int16(countryCode)) ?? ISO3166.Country.unknown
let location = record.object(forKey: "location") as? CLLocation
self.id = record.recordID.recordName
self.creatorID = creatorID
self.date = date
self.location = location
self.colors = colors
self.isoCountry = isoCountry

self = RemoteMood(id: record.recordID.recordName, creatorID: creatorID, date: date, location: location, colors: colors, isoCountry: isoCountry)
}
}

Expand Down
11 changes: 3 additions & 8 deletions Moody/MoodySync/ConsoleRemote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ final class ConsoleRemote: MoodyRemote {

func upload(_ moods: [Mood], completion: @escaping ([RemoteMood], RemoteError?) -> ()) {
log("Uploading \(moods.count) moods")
let remoteMoods = moods.map { RemoteMood(mood: $0) }.flatMap { $0 }
let remoteMoods = moods.map { RemoteMood(mood: $0) }.compactMap { $0 }
completion(remoteMoods, nil)
}

func remove(_ moods: [Mood], completion: @escaping ([RemoteRecordID], RemoteError?) -> ()) {
log("Deleting \(moods.count) moods")
let ids = moods.map { $0.remoteIdentifier }.flatMap { $0 }
let ids = moods.map { $0.remoteIdentifier }.compactMap { $0 }
completion(ids, nil)
}

Expand All @@ -51,12 +51,7 @@ final class ConsoleRemote: MoodyRemote {

extension RemoteMood {
fileprivate init?(mood: Mood) {
self.id = "__dummyId__"
self.creatorID = nil
self.date = mood.date
self.location = mood.location
self.colors = mood.colors
self.isoCountry = mood.country?.iso3166Code ?? .unknown
self = RemoteMood(id: "__dummyId__", creatorID: nil, date: mood.date, location: mood.location, colors: mood.colors, isoCountry: (mood.country?.iso3166Code ?? .unknown))
}
}

Expand Down
2 changes: 1 addition & 1 deletion Moody/MoodySync/MoodDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ extension MoodDownloader {

fileprivate func insert(_ remoteMoods: [RemoteMood], into context: NSManagedObjectContext) {
let existingMoods = { () -> [RemoteRecordID: Mood] in
let ids = remoteMoods.map { $0.id }.flatMap { $0 }
let ids = remoteMoods.map { $0.id }.compactMap { $0 }
let moods = Mood.fetch(in: context) { request in
request.predicate = Mood.predicateForRemoteIdentifiers(ids)
request.returnsObjectsAsFaults = false
Expand Down
2 changes: 1 addition & 1 deletion Moody/MoodySync/SyncContextOwner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import CoreDataHelpers
///
/// This protocol merges changes from the view context into the sync context and vice versa.
/// It calls its `process(changedLocalObjects:)` methods when objects have changed.
protocol ContextOwner: class, ObserverTokenStore {
protocol ContextOwner: ObserverTokenStore {
/// The view managed object context.
var viewContext: NSManagedObjectContext { get }
/// The managed object context that is used to perform synchronization with the backend.
Expand Down
9 changes: 5 additions & 4 deletions Moody/lib/DominantColor/ColorSpaceConversion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ extension ARGBPixel_t {
-0.091169, 0.25243, 0.015708,
0.0009209, -0.0025498, 0.1786,
]
self.a = UInt8.max
self.r = UInt8(max(min(xyz.x * matrix[0] + xyz.y * matrix[1] + xyz.z * matrix[2], Float(UInt8.max)), 0))
self.g = UInt8(max(min(xyz.x * matrix[3] + xyz.y * matrix[4] + xyz.z * matrix[5], Float(UInt8.max)), 0))
self.b = UInt8(max(min(xyz.x * matrix[6] + xyz.y * matrix[7] + xyz.z * matrix[8], Float(UInt8.max)), 0))
let a = UInt8.max
let r = UInt8(max(min(xyz.x * matrix[0] + xyz.y * matrix[1] + xyz.z * matrix[2], Float(UInt8.max)), 0))
let g = UInt8(max(min(xyz.x * matrix[3] + xyz.y * matrix[4] + xyz.z * matrix[5], Float(UInt8.max)), 0))
let b = UInt8(max(min(xyz.x * matrix[6] + xyz.y * matrix[7] + xyz.z * matrix[8], Float(UInt8.max)), 0))
self = ARGBPixel_t(a: a, r: r, g: g, b: b)
}
init(lab: LABPixel) {
let xyz = XYZ(lab: lab)
Expand Down
2 changes: 1 addition & 1 deletion SharedCode/ManagedObjectObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public final class ManagedObjectObserver {
}

deinit {
NotificationCenter.default.removeObserver(token)
NotificationCenter.default.removeObserver(token as Any)
}


Expand Down
9 changes: 2 additions & 7 deletions SharedCode/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,8 @@ extension URL {

extension String {
public func removingCharacters(in set: CharacterSet) -> String {
var chars = characters
for idx in chars.indices.reversed() {
if set.contains(String(chars[idx]).unicodeScalars.first!) {
chars.remove(at: idx)
}
}
return String(chars)
let filtered = unicodeScalars.lazy.filter { !set.contains($0) }
return String(String.UnicodeScalarView(filtered))
}
}

Expand Down