diff --git a/CODistributedNotificationCenter.h b/CODistributedNotificationCenter.h new file mode 100644 index 000000000..edb5e0cbf --- /dev/null +++ b/CODistributedNotificationCenter.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2014 Quentin Mathe + + Date: July 2014 + License: MIT (see COPYING) + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * @group Utilities + * @abstract Distributed notification center compatible with sandboxing. + * + * When sandboxing is enabled, posting a distributed notification results + * in a normal notification. + * + * For non-sandboxed applications on macOS, we use + * NSDistributedNotificationCenter to keep multiple store instances (using the + * same UUID) in sync, accross processes and inside the current process. For + * sandboxed applications on iOS or macOS, this is the same, except we don't + * support the 'accross processes' case. + * + * We cannot ignore distributed notifications in a sandboxed app, because we + * support keeping in sync two editing contexts backed by two distinct stores + * objects with the same UUID. + * + * See also COSQLiteStore and COUndoTrackStore. + **/ +@interface CODistributedNotificationCenter : NSObject +/** + * Returns the default distributed notification center. + */ ++ (CODistributedNotificationCenter *)defaultCenter; +/** + * Adds an observer for the given selector, notification name and object identifier. + */ +- (void)addObserver: (id)observer + selector: (SEL)aSelector + name: (nullable NSNotificationName)aName + object: (nullable NSString *)anObject; +/** + * Removes an observer. + */ +- (void)removeObserver: (id)observer; +/** + * Posts a notification with the given sender and info. + * + * deliverImmediately is ignored, and considered as YES all the time. + */ +- (void)postNotificationName: (nullable NSNotificationName)aName + object: (nullable NSString *)aSender + userInfo: (nullable NSDictionary *)userInfo + deliverImmediately: (BOOL)deliverImmediately; +@end + +NS_ASSUME_NONNULL_END diff --git a/CODistributedNotificationCenter.m b/CODistributedNotificationCenter.m new file mode 100644 index 000000000..bd23cba11 --- /dev/null +++ b/CODistributedNotificationCenter.m @@ -0,0 +1,74 @@ +/* + Copyright (C) 2014 Quentin Mathe + + Date: July 2014 + License: MIT (see COPYING) + */ + +#import "CODistributedNotificationCenter.h" + +@implementation CODistributedNotificationCenter + +static CODistributedNotificationCenter *defaultCenter = nil; + ++ (void)initialize +{ + if ([self class] != self) + return; + + defaultCenter = [[self alloc] init]; +} + ++ (CODistributedNotificationCenter *)defaultCenter +{ + return defaultCenter; +} + +- (void)addObserver: (id)observer + selector: (SEL)aSelector + name: (nullable NSNotificationName)aName + object: (nullable NSString *)anObject +{ +#if !(SANDBOXED) && !(TARGET_OS_IPHONE) + [[NSDistributedNotificationCenter defaultCenter] + addObserver: observer + selector: aSelector + name: aName + object: anObject]; +#else + [[NSNotificationCenter defaultCenter] + addObserver: observer + selector: aSelector + name: aName + object: anObject]; +#endif +} + +- (void)removeObserver: (id)observer { +#if !(SANDBOXED) && !(TARGET_OS_IPHONE) + [[NSDistributedNotificationCenter defaultCenter] removeObserver: observer]; +#else + [[NSNotificationCenter defaultCenter] removeObserver: observer]; +#endif +} + +- (void)postNotificationName: (nullable NSNotificationName)aName + object: (nullable NSString *)aSender + userInfo: (nullable NSDictionary *)userInfo + deliverImmediately: (BOOL)deliverImmediately +{ +#if !(SANDBOXED) && !(TARGET_OS_IPHONE) + [[NSDistributedNotificationCenter defaultCenter] + postNotificationName: aName + object: aSender + userInfo: userInfo + deliverImmediately: deliverImmediately]; +#else + [[NSNotificationCenter defaultCenter] + postNotificationName: aName + object: aSender + userInfo: userInfo]; +#endif +} + +@end diff --git a/Core/COCrossPersistentRootDeadRelationshipCache.h b/Core/COCrossPersistentRootDeadRelationshipCache.h index c809b80c1..6f02829db 100644 --- a/Core/COCrossPersistentRootDeadRelationshipCache.h +++ b/Core/COCrossPersistentRootDeadRelationshipCache.h @@ -59,7 +59,7 @@ NS_ASSUME_NONNULL_BEGIN * * For referring object graph contexts, when unloaded or finalized, the * deallocation will trigger their removal of their inner objects from the hash - * tables in the cache on 10.8 or iOS 6 or higher, but not on 10.7. + * tables in the cache on 10.8 or iOS 6 or higher, which we require. */ - (void)removePath: (COPath *)aPath; diff --git a/Core/COCrossPersistentRootDeadRelationshipCache.m b/Core/COCrossPersistentRootDeadRelationshipCache.m index 1cdcf6c32..8091c11f6 100644 --- a/Core/COCrossPersistentRootDeadRelationshipCache.m +++ b/Core/COCrossPersistentRootDeadRelationshipCache.m @@ -16,11 +16,7 @@ - (instancetype)init { SUPERINIT; _pathToReferringObjects = [NSMutableDictionary new]; -#if TARGET_OS_IPHONE _referringObjectToPaths = [NSMapTable weakToStrongObjectsMapTable]; -#else - _referringObjectToPaths = [NSMapTable mapTableWithWeakToStrongObjects]; -#endif return self; } @@ -35,11 +31,7 @@ - (void)addReferringObject: (COObject *)aReferrer // FIXME: If we don't ditch 10.7 support, we need a reverse mapping // from each referringObject to a path set, that can be used to remove // the referring objects when their object graph context is discarded. -#if TARGET_OS_IPHONE referringObjects = [NSHashTable weakObjectsHashTable]; -#else - referringObjects = [NSHashTable hashTableWithWeakObjects]; -#endif _pathToReferringObjects[aPath] = referringObjects; } diff --git a/Core/COEditingContext.m b/Core/COEditingContext.m index 46eacadd7..2ee1d7b99 100644 --- a/Core/COEditingContext.m +++ b/Core/COEditingContext.m @@ -23,9 +23,7 @@ #import "COCrossPersistentRootDeadRelationshipCache.h" #import "CORevisionCache.h" #import "COStoreTransaction.h" -#if TARGET_OS_IPHONE -#import "NSDistributedNotificationCenter.h" -#endif +#import "CODistributedNotificationCenter.h" @implementation COEditingContext @@ -81,7 +79,7 @@ - (instancetype)initWithStore: (COSQLiteStore *)store name: COStorePersistentRootsDidChangeNotification object: _store]; - [[NSDistributedNotificationCenter defaultCenter] + [[CODistributedNotificationCenter defaultCenter] addObserver: self selector: @selector(distributedStorePersistentRootsDidChange:) name: COStorePersistentRootsDidChangeNotification @@ -117,7 +115,7 @@ - (instancetype)init - (void)dealloc { - [[NSDistributedNotificationCenter defaultCenter] removeObserver: self]; + [[CODistributedNotificationCenter defaultCenter] removeObserver: self]; [[NSNotificationCenter defaultCenter] removeObserver: self]; } diff --git a/Core/COPrimitiveCollection.m b/Core/COPrimitiveCollection.m index ff5c77798..17897594e 100644 --- a/Core/COPrimitiveCollection.m +++ b/Core/COPrimitiveCollection.m @@ -83,11 +83,7 @@ - (BOOL)isMutable - (NSPointerArray *)makeBacking { -#if TARGET_OS_IPHONE return [NSPointerArray strongObjectsPointerArray]; -#else - return [NSPointerArray pointerArrayWithStrongObjects]; -#endif } - (instancetype)init @@ -250,7 +246,7 @@ - (void)insertObject: (id)anObject atIndex: (NSUInteger)index COThrowExceptionIfNotMutable(_permanentlyMutable, _temporaryMutable); COThrowExceptionIfOutOfBounds(self, index, YES); - // NSPointerArray on 10.7 doesn't allow inserting at the end using index == count, so + // NSPointerArray on 10.9 (at least) doesn't allow inserting at the end using index == count, so // call addPointer in that case as a workaround. if (index == _externalIndexToBackingIndex.count) { @@ -366,20 +362,12 @@ @implementation COUnsafeRetainedMutableArray - (NSPointerArray *)makeBacking { -#if TARGET_OS_IPHONE return [NSPointerArray weakObjectsPointerArray]; -#else - return [NSPointerArray pointerArrayWithWeakObjects]; -#endif } - (NSHashTable *)makeBackingHashTable { -#if TARGET_OS_IPHONE return [NSHashTable weakObjectsHashTable]; -#else - return [NSHashTable hashTableWithWeakObjects]; -#endif } - (instancetype)initWithObjects: (const id[])objects count: (NSUInteger)count @@ -672,11 +660,7 @@ @implementation COUnsafeRetainedMutableSet - (NSHashTable *)makeBacking { -#if TARGET_OS_IPHONE return [NSHashTable weakObjectsHashTable]; -#else - return [NSHashTable hashTableWithWeakObjects]; -#endif } @end diff --git a/CoreObject.xcodeproj/project.pbxproj b/CoreObject.xcodeproj/project.pbxproj index b3b08988e..7b10ebeb1 100644 --- a/CoreObject.xcodeproj/project.pbxproj +++ b/CoreObject.xcodeproj/project.pbxproj @@ -3,10 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ + 6001FA89272C3255000FDD6A /* CODistributedNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 60882F1F197E629F00484033 /* CODistributedNotificationCenter.m */; }; 6002E21D197FD6B200AC9150 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F24197EA24900484033 /* AppKit.framework */; }; 6002E21E197FD73A00AC9150 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F24197EA24900484033 /* AppKit.framework */; }; 6002E280197FD90300AC9150 /* libSystem.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 60F91ED6197D2CA2009F47D7 /* libSystem.dylib */; }; @@ -108,9 +109,9 @@ 60882F1B197D50C000484033 /* COObjectToArchivedData.m in Sources */ = {isa = PBXBuildFile; fileRef = 608D25F5192B475200BB7461 /* COObjectToArchivedData.m */; }; 60882F1C197D50CA00484033 /* CORectToString.m in Sources */ = {isa = PBXBuildFile; fileRef = 6633F10D185515F1009CE6F7 /* CORectToString.m */; }; 60882F1D197D50CE00484033 /* CORectToString.h in Headers */ = {isa = PBXBuildFile; fileRef = 6633F10C185515F1009CE6F7 /* CORectToString.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 60882F20197E629F00484033 /* NSDistributedNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 60882F1E197E629F00484033 /* NSDistributedNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 60882F21197E629F00484033 /* NSDistributedNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 60882F1F197E629F00484033 /* NSDistributedNotificationCenter.m */; }; - 60882F22197E62FC00484033 /* NSDistributedNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 60882F1E197E629F00484033 /* NSDistributedNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 60882F20197E629F00484033 /* CODistributedNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 60882F1E197E629F00484033 /* CODistributedNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 60882F21197E629F00484033 /* CODistributedNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 60882F1F197E629F00484033 /* CODistributedNotificationCenter.m */; }; + 60882F22197E62FC00484033 /* CODistributedNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 60882F1E197E629F00484033 /* CODistributedNotificationCenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 60882F25197EA24900484033 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F24197EA24900484033 /* AppKit.framework */; }; 60882F27197EA25600484033 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F26197EA25600484033 /* Foundation.framework */; }; 60882F29197EA26900484033 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 60882F28197EA26900484033 /* libsqlite3.dylib */; }; @@ -1080,8 +1081,8 @@ 6083223619795D18008D9F9D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; 6083223819795D21008D9F9D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 6083223C19797DE2008D9F9D /* COCocoaTouchCompatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = COCocoaTouchCompatibility.h; path = iOS/COCocoaTouchCompatibility.h; sourceTree = SOURCE_ROOT; }; - 60882F1E197E629F00484033 /* NSDistributedNotificationCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSDistributedNotificationCenter.h; path = iOS/NSDistributedNotificationCenter.h; sourceTree = SOURCE_ROOT; }; - 60882F1F197E629F00484033 /* NSDistributedNotificationCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSDistributedNotificationCenter.m; path = iOS/NSDistributedNotificationCenter.m; sourceTree = SOURCE_ROOT; }; + 60882F1E197E629F00484033 /* CODistributedNotificationCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CODistributedNotificationCenter.h; sourceTree = SOURCE_ROOT; }; + 60882F1F197E629F00484033 /* CODistributedNotificationCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CODistributedNotificationCenter.m; sourceTree = SOURCE_ROOT; }; 60882F24197EA24900484033 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 60882F26197EA25600484033 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 60882F28197EA26900484033 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; @@ -1702,8 +1703,6 @@ isa = PBXGroup; children = ( 6083223C19797DE2008D9F9D /* COCocoaTouchCompatibility.h */, - 60882F1E197E629F00484033 /* NSDistributedNotificationCenter.h */, - 60882F1F197E629F00484033 /* NSDistributedNotificationCenter.m */, 60F91EC6197D1D1C009F47D7 /* main.m */, 6028484D1BBAB5820094CDB0 /* Default-568h@2x.png */, 60F91EC8197D1D7F009F47D7 /* TestCoreObject-Info.plist */, @@ -2105,6 +2104,8 @@ 6686BDC712592C1B0065DE1A /* Utilities */ = { isa = PBXGroup; children = ( + 60882F1E197E629F00484033 /* CODistributedNotificationCenter.h */, + 60882F1F197E629F00484033 /* CODistributedNotificationCenter.m */, 609C00E21704C42200D01AAB /* COError.h */, 609C00E31704C42200D01AAB /* COError.m */, 6612113E1821986B003AEC29 /* CODateSerialization.h */, @@ -2605,7 +2606,7 @@ 60E08D3019792FFA00D1B7AD /* COCommandUndeletePersistentRoot.h in Headers */, 60E08D0219792FFA00D1B7AD /* COBookmark.h in Headers */, 60E08D3219792FFA00D1B7AD /* COItemGraphEdit.h in Headers */, - 60882F20197E629F00484033 /* NSDistributedNotificationCenter.h in Headers */, + 60882F20197E629F00484033 /* CODistributedNotificationCenter.h in Headers */, 60B1568F19B861D3006D5EEF /* COObjectGraphContext+Debugging.h in Headers */, 60E08D6119792FFA00D1B7AD /* COObjectGraphContext+GarbageCollection.h in Headers */, 60E08D5C19792FFA00D1B7AD /* COStoreWriteRevision.h in Headers */, @@ -2653,7 +2654,7 @@ buildActionMask = 2147483647; files = ( 6036436C1B3800B400DC685B /* COHistoryCompaction.h in Headers */, - 60882F22197E62FC00484033 /* NSDistributedNotificationCenter.h in Headers */, + 60882F22197E62FC00484033 /* CODistributedNotificationCenter.h in Headers */, 609C00801704C2BA00D01AAB /* CORevision.h in Headers */, 609C00941704C3DA00D01AAB /* COEditingContext.h in Headers */, 603643841B394E8800DC685B /* COUndoTrackHistoryCompaction.h in Headers */, @@ -2970,7 +2971,7 @@ }; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "CoreObject" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -3320,7 +3321,7 @@ 60E08CBA19792F4600D1B7AD /* COBezierPath.m in Sources */, 60E08CB419792F4600D1B7AD /* COSQLiteStorePersistentRootBackingStore.m in Sources */, 60E08CE119792F4600D1B7AD /* COLeastCommonAncestor.m in Sources */, - 60882F21197E629F00484033 /* NSDistributedNotificationCenter.m in Sources */, + 60882F21197E629F00484033 /* CODistributedNotificationCenter.m in Sources */, 60E08CAB19792F4600D1B7AD /* CODictionary.m in Sources */, 60E08CDF19792F4600D1B7AD /* COSequenceModification.m in Sources */, 60E08CBF19792F4600D1B7AD /* COAttributedStringDiff.m in Sources */, @@ -3594,6 +3595,7 @@ 663CE29A17C07ED800E729F5 /* COCommandDeleteBranch.m in Sources */, 663CE29C17C07ED800E729F5 /* COCommandSetBranchMetadata.m in Sources */, 663CE29E17C07ED800E729F5 /* COCommandSetCurrentBranch.m in Sources */, + 6001FA89272C3255000FDD6A /* CODistributedNotificationCenter.m in Sources */, 663CE2A017C07ED800E729F5 /* COCommandSetCurrentVersionForBranch.m in Sources */, 663CE2A217C07ED800E729F5 /* COUndoTrackStore.m in Sources */, 663CE2B717C0B05900E729F5 /* COEditingContext+Undo.m in Sources */, @@ -3850,7 +3852,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "iOS/TestCoreObject-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -3883,7 +3888,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "iOS/TestCoreObject-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -3921,7 +3929,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "TestCoreObject (iOS) copy2-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -3954,7 +3965,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "TestCoreObject (iOS) copy2-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -4099,7 +4113,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "iOS/TestCoreObject-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -4132,7 +4149,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "iOS/TestCoreObject-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)/usr/lib/system", @@ -4176,6 +4196,7 @@ DYLIB_COMPATIBILITY_VERSION = 0; DYLIB_CURRENT_VERSION = 5; FRAMEWORK_VERSION = A; + GCC_PREPROCESSOR_DEFINITIONS = "SANDBOXED=1"; INFOPLIST_FILE = CoreObjectInfo.plist; INSTALL_PATH = "@rpath"; OTHER_CFLAGS = ( @@ -4201,6 +4222,7 @@ DYLIB_COMPATIBILITY_VERSION = 0; DYLIB_CURRENT_VERSION = 5; FRAMEWORK_VERSION = A; + GCC_PREPROCESSOR_DEFINITIONS = "SANDBOXED=1"; INFOPLIST_FILE = CoreObjectInfo.plist; INSTALL_PATH = "@rpath"; OTHER_CFLAGS = ( @@ -4248,6 +4270,8 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -4263,8 +4287,8 @@ GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MACOSX_DEPLOYMENT_TARGET = 10.7; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "-DDEBUG"; SDKROOT = macosx; @@ -4279,6 +4303,8 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -4289,8 +4315,8 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MACOSX_DEPLOYMENT_TARGET = 10.7; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; SDKROOT = macosx; WARNING_CFLAGS = ( "-Wall", diff --git a/Debugging/COSQLiteStore+Graphviz.m b/Debugging/COSQLiteStore+Graphviz.m index f668ca89f..7c4b08e10 100644 --- a/Debugging/COSQLiteStore+Graphviz.m +++ b/Debugging/COSQLiteStore+Graphviz.m @@ -82,7 +82,7 @@ - (NSString *)dotGraphForPersistentRootUUID: (ETUUID *)aPersistentRoot COPersistentRootInfo *info = [self persistentRootInfoForUUID: aPersistentRoot]; - assert(dispatch_get_current_queue() != queue_); + assert(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) != dispatch_queue_get_label(queue_)); dispatch_sync(queue_, ^() { @@ -178,12 +178,9 @@ void COViewDOTGraphFile(NSString *dotFilePath) { continue; } - - // NOTE: Using NSTask rather than system() breaks 'po [objectGraphContext showGraph]' in LLDB on 10.7 - system([[NSString stringWithFormat: @"%@ -Tpdf '%@' -o '%@'", - executablePath, - dotFilePath, - pdfPath] UTF8String]); + NSTask *task = [NSTask launchedTaskWithLaunchPath: executablePath + arguments: @[@"-Tpdf", dotFilePath, @"-o", pdfPath]]; + [task waitUntilExit]; [[NSWorkspace sharedWorkspace] openFile: pdfPath]; break; } diff --git a/Extras/ValueTransformers/COColorToHTMLString.m b/Extras/ValueTransformers/COColorToHTMLString.m index be32ccb5c..a32ed2a98 100644 --- a/Extras/ValueTransformers/COColorToHTMLString.m +++ b/Extras/ValueTransformers/COColorToHTMLString.m @@ -39,9 +39,9 @@ static CGFloat FractionFromHex(NSString *twoChars) NSColor *rgbColor = color; CGFloat a, r, g, b; - // NOTE: iOS does not support device-independent or generic color spaces + // NOTE: On iOS, UIColor uses sRGB color space by default #if !(TARGET_OS_IPHONE) - rgbColor = [color colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; + rgbColor = [color colorUsingColorSpace: NSColorSpace.sRGBColorSpace]; #endif [rgbColor getRed: &r green: &g blue: &b alpha: &a]; @@ -62,7 +62,7 @@ static CGFloat FractionFromHex(NSString *twoChars) #if TARGET_OS_IPHONE return [UIColor colorWithRed: r green: g blue: b alpha: a]; #else - return [NSColor colorWithCalibratedRed: r green: g blue: b alpha: a]; + return [NSColor colorWithSRGBRed: r green: g blue: b alpha: a]; #endif } diff --git a/Model/COLibrary.m b/Model/COLibrary.m index d3ab45aec..5c131457f 100644 --- a/Model/COLibrary.m +++ b/Model/COLibrary.m @@ -87,7 +87,7 @@ - (COSmartGroup *)libraryGroup COSmartGroup *group = [[COSmartGroup alloc] initWithObjectGraphContext: _internalTransientObjectGraphContext]; [group setName: _(@"All Objects")]; - group.targetCollection = [[[self.persistentRoots mappedCollection] rootObject] allObjects]; + group.targetCollection = [(id)[[self.persistentRoots mappedCollection] rootObject] allObjects]; #ifdef GNUSTEP group.predicate = [NSPredicate predicateWithFormat: @"isLibrary == YES"]; #else diff --git a/StorageDataModel/COItem+JSON.m b/StorageDataModel/COItem+JSON.m index bd5d7c0e2..be73d9a02 100644 --- a/StorageDataModel/COItem+JSON.m +++ b/StorageDataModel/COItem+JSON.m @@ -167,22 +167,6 @@ static id plistValueForValue(id aValue, COType aType) // JSON-compatible plist -> COItem attribute value -/* - * Returning the parsed value as a NSNumber rather a NSDecimalNumber to ensure - * the rounding is the same than the serialized NSNumber object. - * - * Without this workaround, 123.456789012 roundtrip doesn't succeed on 10.7 (see - * -testJSONDoubleEquality in TestItem.m)). - * - * For 123.456789012, NSJSONSerialization returns a NSDecimalNumber, but the - * rounding doesn't produce the same internal representation than a NSNumber - * initialized with the same double value. - */ -static inline NSNumber *basicNumberFromDecimalNumber(NSNumber *aValue) -{ - return @(aValue.description.doubleValue); -} - static id valueForPrimitivePlistValue(id aValue, COType aType) { if (aValue == [NSNull null]) @@ -195,7 +179,7 @@ static id valueForPrimitivePlistValue(id aValue, COType aType) case kCOTypeInt64: return aValue; case kCOTypeDouble: - return basicNumberFromDecimalNumber(aValue); + return aValue; case kCOTypeString: return aValue; case kCOTypeAttachment: diff --git a/StorageDataModel/COItemGraph.h b/StorageDataModel/COItemGraph.h index 883203b1d..b1ce6897b 100644 --- a/StorageDataModel/COItemGraph.h +++ b/StorageDataModel/COItemGraph.h @@ -10,6 +10,8 @@ @class ETUUID; @class COItem, COMutableItem; +NS_ASSUME_NONNULL_BEGIN + /** * @group Storage Data Model * @abstract @@ -28,21 +30,21 @@ /** * Returns the entry point UUID. */ -@property (nonatomic, readonly) ETUUID *rootItemUUID; +@property (nonatomic, readonly, nullable) ETUUID *rootItemUUID; /** * Returns an immutable item for the UUID. */ -- (COItem *)itemForUUID: (ETUUID *)aUUID; +- (nullable COItem *)itemForUUID: (ETUUID *)aUUID; /** * Returns all the item UUIDs in the graph, including -rootItemUUID. */ -@property (nonatomic, readonly) NSArray *itemUUIDs; +@property (nonatomic, readonly) NSArray *itemUUIDs; /** * Returns all the items in the graph. * * The returned item count is the same than -itemUUIDs. */ -@property (nonatomic, readonly) NSArray *items; +@property (nonatomic, readonly) NSArray *items; /** * Inserts the items in the graph, or updates existing items when the graph * contains items with matching UUIDs. @@ -51,7 +53,7 @@ * * May broadcast a change notification, up to the subclass. */ -- (void)insertOrUpdateItems: (NSArray *)items; +- (void)insertOrUpdateItems: (NSArray *)items; @end @@ -77,16 +79,16 @@ /** @taskunit Initialization */ -+ (COItemGraph *)itemGraphWithItemsRootFirst: (NSArray *)items; ++ (COItemGraph *)itemGraphWithItemsRootFirst: (NSArray *)items; /** * N.B. items doesn't need to contain rootItemUUID. */ -- (instancetype)initWithItemForUUID: (NSDictionary *)itemForUUID - rootItemUUID: (ETUUID *)root NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithItemForUUID: (NSDictionary *)itemForUUID + rootItemUUID: (nullable ETUUID *)root NS_DESIGNATED_INITIALIZER; /** * N.B. items doesn't need to contain rootItemUUID. */ -- (instancetype)initWithItems: (NSArray *)items +- (instancetype)initWithItems: (NSArray *)items rootItemUUID: (ETUUID *)root; - (instancetype)initWithItemGraph: (id )aGraph; @@ -97,7 +99,7 @@ /** * See -[COItemGraph rootItemUUID]. */ -@property (nonatomic, strong) ETUUID *rootItemUUID; +@property (nonatomic, strong, nullable) ETUUID *rootItemUUID; /** * See -[COItemGraph itemForUUID:]. */ @@ -105,17 +107,17 @@ /** * See -[COItemGraph itemUUIDs]. */ -@property (nonatomic, readonly) NSArray *itemUUIDs; +@property (nonatomic, readonly) NSArray *itemUUIDs; /** * Returns all the items in the graph. * * The returned item count is the same than -itemUUIDs. */ -@property (nonatomic, readonly) NSArray *items; +@property (nonatomic, readonly) NSArray *items; /** * See -[COItemGraph insertOrUpdateItems:]. */ -- (void)insertOrUpdateItems: (NSArray *)items; +- (void)insertOrUpdateItems: (NSArray *)items; /** * Adds the items from the given item graph to the receiver. * @@ -149,4 +151,6 @@ BOOL COItemGraphEqualToItemGraph(id first, id second /** * If aGraph.rootItemUUID is nil, returns the empty set. */ -NSSet *COItemGraphReachableUUIDs(id aGraph); +NSSet *COItemGraphReachableUUIDs(id aGraph); + +NS_ASSUME_NONNULL_END diff --git a/StorageDataModel/COItemGraph.m b/StorageDataModel/COItemGraph.m index d3e2d1825..d6b1fa333 100644 --- a/StorageDataModel/COItemGraph.m +++ b/StorageDataModel/COItemGraph.m @@ -8,6 +8,7 @@ #import "COItemGraph.h" #import #import +#import #import "COItem.h" #import "COItem+JSON.h" #import "COItem+Binary.h" diff --git a/Store/COSQLiteStore.h b/Store/COSQLiteStore.h index 6698e0aa6..7aacbc23a 100644 --- a/Store/COSQLiteStore.h +++ b/Store/COSQLiteStore.h @@ -390,7 +390,7 @@ extern NSString *const COPersistentRootAttributeUsedSize; * * NOTE: Unstable API */ -- (NSArray *)revisionInfosForBackingStoreOfPersistentRootUUID: (ETUUID *)aPersistentRoot; +- (NSArray *)revisionInfosForBackingStoreOfPersistentRootUUID: (ETUUID *)aPersistentRoot; /** * Returns a delta between the given revision IDs. * The delta is uses the granularity of single inner objects, but not individual properties. @@ -420,8 +420,8 @@ extern NSString *const COPersistentRootAttributeUsedSize; /** * Only returns non-deleted persistent root UUIDs. */ -@property (nonatomic, readonly) NSArray *persistentRootUUIDs; -@property (nonatomic, readonly) NSArray *deletedPersistentRootUUIDs; +@property (nonatomic, readonly) NSArray *persistentRootUUIDs; +@property (nonatomic, readonly) NSArray *deletedPersistentRootUUIDs; /** * @return a snapshot of the state of a persistent root, or nil if diff --git a/Store/COSQLiteStore.m b/Store/COSQLiteStore.m index 9cda29d02..1476fc9d4 100644 --- a/Store/COSQLiteStore.m +++ b/Store/COSQLiteStore.m @@ -18,12 +18,7 @@ #import "COJSONSerialization.h" #import "COStoreTransaction.h" #import "COStoreAction.h" - -#if TARGET_OS_IPHONE - -#import "NSDistributedNotificationCenter.h" - -#endif +#import "CODistributedNotificationCenter.h" #import "FMDatabaseAdditions.h" @@ -125,9 +120,7 @@ - (void)dealloc db_ = nil; }); -#if !(TARGET_OS_IPHONE) - // N.B.: We are using deployment target 10.7, so ARC does not manage libdispatch objects. - // If we switch to deployment target 10.8, ARC will manage libdispatch objects automatically. +#ifdef GNUSTEP // For GNUstep, ARC doesn't manage libdispatch objects since libobjc2 doesn't support it // currently (we compile CoreObject with -DOS_OBJECT_USE_OBJC=0). dispatch_release(queue_); @@ -1047,7 +1040,7 @@ - (void)postCommitNotificationsWithUserInfo: (NSDictionary *)userInfo object: self userInfo: userInfo]; - [[NSDistributedNotificationCenter defaultCenter] + [[CODistributedNotificationCenter defaultCenter] postNotificationName: COStorePersistentRootsDidChangeNotification object: [self.UUID stringValue] userInfo: userInfo diff --git a/Store/COStoreTransaction.h b/Store/COStoreTransaction.h index c0fb6e014..6de481210 100644 --- a/Store/COStoreTransaction.h +++ b/Store/COStoreTransaction.h @@ -30,7 +30,7 @@ /** @taskunit Transaction ID */ -@property (nonatomic, readonly) NSArray *persistentRootUUIDs; +@property (nonatomic, readonly) NSArray *persistentRootUUIDs; /** * Returns YES if this transaction contains an action affecting the mutable diff --git a/Tests/StorageDataModel/TestItem.m b/Tests/StorageDataModel/TestItem.m index e04a0077e..364f8d1d4 100644 --- a/Tests/StorageDataModel/TestItem.m +++ b/Tests/StorageDataModel/TestItem.m @@ -82,16 +82,13 @@ - (void)testJSONDoubleEquality NSNumber *newValueFromDesc = @(roundTripValue.description.doubleValue); #ifndef GNUSTEP - // NOTE: Doesn't matter on GNUstep since newValue is not a NSDecimalNumber, - // and we don't have to convert it into a NSDoubleNumber (unlike on 10.7). + // NOTE: Doesn't matter on GNUstep since newValue is not a NSDecimalNumber. UKTrue([[NSDecimalNumber defaultBehavior] scale] == NSDecimalNoScale); #endif NSLog(@"Double representation in JSON: %@", [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]); - /* Rounding is visible in the ouput for numbers that contain more than two - decimals on 10.7 (e.g. 123.45 output is the same for all numbers). */ NSLog(@"value doubleValue: %.20f, description: %@, class: %@", value.doubleValue, value, [value class]); NSLog(@"decimalValue doubleValue: %.20f, description: %@, class: %@", diff --git a/Tests/TestCommon.m b/Tests/TestCommon.m index 1e0052398..22fffeb47 100644 --- a/Tests/TestCommon.m +++ b/Tests/TestCommon.m @@ -91,8 +91,6 @@ - (instancetype)init - (void)dealloc { #ifdef DELETE_STORE_AFTER_EACH_TEST_METHOD - // FIXME: For Mac OS X 10.7, this is unsupported, SQLite disk errors - // (DB Error: 10 "disk I/O error") appear in TestStoreSQLite.m. [[self class] deleteStores]; #endif } diff --git a/Undo/COUndoTrack.m b/Undo/COUndoTrack.m index 0d78de69b..d0b030399 100644 --- a/Undo/COUndoTrack.m +++ b/Undo/COUndoTrack.m @@ -884,7 +884,7 @@ - (void)postNotificationsForTrackName: (NSString *)aTrack object: self userInfo: userInfo]; // FIXME: Implement distributed notification support - // [[NSDistributedNotificationCenter defaultCenter] postNotificationName: COStorePersistentRootDidChangeNotification + // [[CODistributedNotificationCenter defaultCenter] postNotificationName: COStorePersistentRootDidChangeNotification // object: [self.UUID stringValue] // userInfo: userInfo // deliverImmediately: NO]; diff --git a/Undo/COUndoTrackStore+Private.h b/Undo/COUndoTrackStore+Private.h index 67d63afc7..5dc3bd061 100644 --- a/Undo/COUndoTrackStore+Private.h +++ b/Undo/COUndoTrackStore+Private.h @@ -11,22 +11,22 @@ @class FMDatabase; @class ETUUID; -NSString *const COUndoTrackStoreTrackDidChangeNotification; +extern NSString *const COUndoTrackStoreTrackDidChangeNotification; // User info keys for COUndoTrackStoreTrackDidChangeNotification -NSString *const COUndoTrackStoreTrackName; +extern NSString *const COUndoTrackStoreTrackName; /** * UUID string */ -NSString *const COUndoTrackStoreTrackHeadCommandUUID; +extern NSString *const COUndoTrackStoreTrackHeadCommandUUID; /** * NSNull or UUID string */ -NSString *const COUndoTrackStoreTrackCurrentCommandUUID; +extern NSString *const COUndoTrackStoreTrackCurrentCommandUUID; /** * NSNumber boolean */ -NSString *const COUndoTrackStoreTrackCompacted; +extern NSString *const COUndoTrackStoreTrackCompacted; @interface COUndoTrackSerializedCommand : NSObject diff --git a/Undo/COUndoTrackStore.m b/Undo/COUndoTrackStore.m index 7303a0361..08bf14bc1 100644 --- a/Undo/COUndoTrackStore.m +++ b/Undo/COUndoTrackStore.m @@ -14,12 +14,7 @@ #import "COEndOfUndoTrackPlaceholderNode.h" #import "COJSONSerialization.h" #import "COSQLiteUtilities.h" - -#if TARGET_OS_IPHONE - -#import "NSDistributedNotificationCenter.h" - -#endif +#import "CODistributedNotificationCenter.h" /* For dispatch_get_current_queue() deprecated on iOS (to prevent to people to use it beside debugging) */ @@ -204,9 +199,7 @@ - (void)dealloc [_db close]; }); -#if !(TARGET_OS_IPHONE) - // N.B.: We are using deployment target 10.7, so ARC does not manage libdispatch objects. - // If we switch to deployment target 10.8, ARC will manage libdispatch objects automatically. +#ifdef GNUSTEP // For GNUstep, ARC doesn't manage libdispatch objects since libobjc2 doesn't support it // currently (we compile CoreObject with -DOS_OBJECT_USE_OBJC=0). dispatch_release(_queue); @@ -738,7 +731,7 @@ - (void)postCommitNotificationsWithUserInfo: (NSDictionary *)userInfo object: self userInfo: userInfo]; - [[NSDistributedNotificationCenter defaultCenter] + [[CODistributedNotificationCenter defaultCenter] postNotificationName: COUndoTrackStoreTrackDidChangeNotification object: [_db databasePath] userInfo: userInfo diff --git a/iOS/NSDistributedNotificationCenter.h b/iOS/NSDistributedNotificationCenter.h deleted file mode 100644 index c4d2c5464..000000000 --- a/iOS/NSDistributedNotificationCenter.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (C) 2014 Quentin Mathe - - Date: July 2014 - License: MIT (see COPYING) - */ - -#import - -#if TARGET_OS_IPHONE - -/** - * @group iOS - * @abstract A fake distributed notification center that operates locally. - * - * This makes possible to support NSDistributedNotificationCenter API on iOS. - * - * On macOS, we use it to keep multiple store instances (using the same UUID) - * in sync, accross processes and inside the current process. On iOS, this is - * the same, except we don't support the 'accross processes' case. - * - * Note: A store cannot be accessed by multiple applications on iOS, due to the - * sandboxing restrictions. - * - * See also COSQLiteStore and COUndoTrackStore. - **/ -@interface CODistributedNotificationCenter : NSNotificationCenter -/** - * Returns the default distributed notification center. - */ -+ (CODistributedNotificationCenter *)defaultCenter; -/** - * Posts a notification with the given sender and info. - * - * deliverImmediately is ignored, and considered as YES all the time. - */ -- (void)postNotificationName: (NSString *)aName - object: (NSString *)aSender - userInfo: (NSDictionary *)userInfo - deliverImmediately: (BOOL)deliverImmediately; -@end - -/** - * AppStore approval process treats NSDistributedNotificationCenter as a private - * API, so we use another name internally. - */ -@compatibility_alias NSDistributedNotificationCenter CODistributedNotificationCenter; - -#endif diff --git a/iOS/NSDistributedNotificationCenter.m b/iOS/NSDistributedNotificationCenter.m deleted file mode 100644 index 65c34ad7f..000000000 --- a/iOS/NSDistributedNotificationCenter.m +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2014 Quentin Mathe - - Date: July 2014 - License: MIT (see COPYING) - */ - -#import "NSDistributedNotificationCenter.h" - -/** - * @group iOS - * @abstract A fake distributed notification center that operates locally. - * - * This makes possible to support NSDistributedNotificationCenter API on iOS. - * - * On macOS, we use it to keep multiple store instances (using the same UUID) - * in sync, accross processes and inside the current process. On iOS, this is - * the same, except we don't support the 'accross processes' case. - * - * Note: A store cannot be accessed by multiple applications on iOS, due to the - * sandboxing restrictions. - * - * See also COSQLiteStore and COUndoTrackStore. - **/ -@implementation CODistributedNotificationCenter - -static CODistributedNotificationCenter *defaultCenter = nil; - -+ (void)initialize -{ - if ([self class] != self) - return; - - defaultCenter = [[self alloc] init]; -} - -+ (CODistributedNotificationCenter *)defaultCenter -{ - return defaultCenter; -} - -- (void)postNotificationName: (NSString *)aName - object: (NSString *)aSender - userInfo: (NSDictionary *)userInfo - deliverImmediately: (BOOL)deliverImmediately -{ - [self postNotificationName: aName object: aSender userInfo: userInfo]; -} - -@end