diff --git a/Notes.xcodeproj/project.pbxproj b/Notes.xcodeproj/project.pbxproj index 750b56d..77543ea 100644 --- a/Notes.xcodeproj/project.pbxproj +++ b/Notes.xcodeproj/project.pbxproj @@ -3,85 +3,92 @@ archiveVersion = 1; classes = { }; - objectVersion = 55; + objectVersion = 56; objects = { /* Begin PBXBuildFile section */ - C41A31C628C49B310019B951 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31C528C49B310019B951 /* AppDelegate.swift */; }; - C41A31C828C49B310019B951 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31C728C49B310019B951 /* SceneDelegate.swift */; }; - C41A31CA28C49B310019B951 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31C928C49B310019B951 /* ViewController.swift */; }; - C41A31CD28C49B310019B951 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C41A31CB28C49B310019B951 /* Main.storyboard */; }; - C41A31D028C49B310019B951 /* Notes.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C41A31CE28C49B310019B951 /* Notes.xcdatamodeld */; }; - C41A31D228C49B320019B951 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C41A31D128C49B320019B951 /* Assets.xcassets */; }; - C41A31D528C49B320019B951 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C41A31D328C49B320019B951 /* LaunchScreen.storyboard */; }; - C41A31E028C49B320019B951 /* NotesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31DF28C49B320019B951 /* NotesTests.swift */; }; - C41A31EA28C49B320019B951 /* NotesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31E928C49B320019B951 /* NotesUITests.swift */; }; - C41A31EC28C49B320019B951 /* NotesUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31EB28C49B320019B951 /* NotesUITestsLaunchTests.swift */; }; - C41A31F928C49DC80019B951 /* NoteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31F828C49DC80019B951 /* NoteViewController.swift */; }; - C41A31FB28C4D8040019B951 /* PreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31FA28C4D8040019B951 /* PreferencesStorage.swift */; }; - C43417F428D4ADB10098C15A /* FileOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43417F328D4ADB10098C15A /* FileOperator.swift */; }; - C43417F628D4ADDB0098C15A /* FileStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43417F528D4ADDB0098C15A /* FileStorage.swift */; }; - C43417FA28D4B9370098C15A /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43417F928D4B9370098C15A /* Document.swift */; }; - C4EEE40728D89C46003DDC24 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE40628D89C46003DDC24 /* UIViewController+Extensions.swift */; }; + C4EEE41F28DB33D8003DDC24 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE41E28DB33D8003DDC24 /* AppDelegate.swift */; }; + C4EEE42128DB33D8003DDC24 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */; }; + C4EEE42328DB33D8003DDC24 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE42228DB33D8003DDC24 /* ViewController.swift */; }; + C4EEE42628DB33D8003DDC24 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C4EEE42428DB33D8003DDC24 /* Main.storyboard */; }; + C4EEE42928DB33D8003DDC24 /* Notes.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE42728DB33D8003DDC24 /* Notes.xcdatamodeld */; }; + C4EEE42B28DB33D9003DDC24 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C4EEE42A28DB33D9003DDC24 /* Assets.xcassets */; }; + C4EEE42E28DB33D9003DDC24 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C4EEE42C28DB33D9003DDC24 /* LaunchScreen.storyboard */; }; + C4EEE43928DB33D9003DDC24 /* NotesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE43828DB33D9003DDC24 /* NotesTests.swift */; }; + C4EEE44328DB33D9003DDC24 /* NotesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE44228DB33D9003DDC24 /* NotesUITests.swift */; }; + C4EEE44528DB33D9003DDC24 /* NotesUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE44428DB33D9003DDC24 /* NotesUITestsLaunchTests.swift */; }; + C4EEE45328DB3423003DDC24 /* NoteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE45128DB3422003DDC24 /* NoteViewController.swift */; }; + C4EEE45428DB3423003DDC24 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE45228DB3423003DDC24 /* UIViewController+Extensions.swift */; }; + C4EEE46728DB3790003DDC24 /* FileOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE46528DB3790003DDC24 /* FileOperator.swift */; }; + C4EEE46928DB3790003DDC24 /* FileStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE46628DB3790003DDC24 /* FileStorage.swift */; }; + C4EEE46A28DB3790003DDC24 /* PreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE46428DB378F003DDC24 /* PreferencesStorage.swift */; }; + C4EEE47628DB3938003DDC24 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C4EEE47528DB3938003DDC24 /* CoreData.framework */; }; + C4EEE48128DB39F1003DDC24 /* Note+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE47F28DB39F1003DDC24 /* Note+CoreDataClass.swift */; }; + C4EEE48228DB39F1003DDC24 /* Note+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE48028DB39F1003DDC24 /* Note+CoreDataProperties.swift */; }; + C4EEE48428DB3B6B003DDC24 /* CoreDataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE48328DB3B6B003DDC24 /* CoreDataStorage.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - C41A31DC28C49B320019B951 /* PBXContainerItemProxy */ = { + C4EEE43528DB33D9003DDC24 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = C41A31BA28C49B310019B951 /* Project object */; + containerPortal = C4EEE41328DB33D8003DDC24 /* Project object */; proxyType = 1; - remoteGlobalIDString = C41A31C128C49B310019B951; + remoteGlobalIDString = C4EEE41A28DB33D8003DDC24; remoteInfo = Notes; }; - C41A31E628C49B320019B951 /* PBXContainerItemProxy */ = { + C4EEE43F28DB33D9003DDC24 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = C41A31BA28C49B310019B951 /* Project object */; + containerPortal = C4EEE41328DB33D8003DDC24 /* Project object */; proxyType = 1; - remoteGlobalIDString = C41A31C128C49B310019B951; + remoteGlobalIDString = C4EEE41A28DB33D8003DDC24; remoteInfo = Notes; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - C41A31C228C49B310019B951 /* Notes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Notes.app; sourceTree = BUILT_PRODUCTS_DIR; }; - C41A31C528C49B310019B951 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - C41A31C728C49B310019B951 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - C41A31C928C49B310019B951 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - C41A31CC28C49B310019B951 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - C41A31CF28C49B310019B951 /* Notes.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Notes.xcdatamodel; sourceTree = ""; }; - C41A31D128C49B320019B951 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - C41A31D428C49B320019B951 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - C41A31D628C49B320019B951 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C41A31DB28C49B320019B951 /* NotesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NotesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - C41A31DF28C49B320019B951 /* NotesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesTests.swift; sourceTree = ""; }; - C41A31E528C49B320019B951 /* NotesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NotesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - C41A31E928C49B320019B951 /* NotesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesUITests.swift; sourceTree = ""; }; - C41A31EB28C49B320019B951 /* NotesUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesUITestsLaunchTests.swift; sourceTree = ""; }; - C41A31F828C49DC80019B951 /* NoteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteViewController.swift; sourceTree = ""; }; - C41A31FA28C4D8040019B951 /* PreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesStorage.swift; sourceTree = ""; }; - C43417F128D4AACD0098C15A /* Notes.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Notes.entitlements; sourceTree = ""; }; - C43417F328D4ADB10098C15A /* FileOperator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileOperator.swift; sourceTree = ""; }; - C43417F528D4ADDB0098C15A /* FileStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileStorage.swift; sourceTree = ""; }; - C43417F928D4B9370098C15A /* Document.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Document.swift; sourceTree = ""; }; - C4EEE40628D89C46003DDC24 /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extensions.swift"; sourceTree = ""; }; + C4EEE41B28DB33D8003DDC24 /* Notes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Notes.app; sourceTree = BUILT_PRODUCTS_DIR; }; + C4EEE41E28DB33D8003DDC24 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + C4EEE42228DB33D8003DDC24 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + C4EEE42528DB33D8003DDC24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + C4EEE42828DB33D8003DDC24 /* Notes.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Notes.xcdatamodel; sourceTree = ""; }; + C4EEE42A28DB33D9003DDC24 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + C4EEE42D28DB33D9003DDC24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + C4EEE42F28DB33D9003DDC24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C4EEE43428DB33D9003DDC24 /* NotesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NotesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + C4EEE43828DB33D9003DDC24 /* NotesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesTests.swift; sourceTree = ""; }; + C4EEE43E28DB33D9003DDC24 /* NotesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NotesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + C4EEE44228DB33D9003DDC24 /* NotesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesUITests.swift; sourceTree = ""; }; + C4EEE44428DB33D9003DDC24 /* NotesUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesUITestsLaunchTests.swift; sourceTree = ""; }; + C4EEE45128DB3422003DDC24 /* NoteViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoteViewController.swift; sourceTree = ""; }; + C4EEE45228DB3423003DDC24 /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extensions.swift"; sourceTree = ""; }; + C4EEE45928DB358A003DDC24 /* Notes.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Notes.entitlements; sourceTree = ""; }; + C4EEE46428DB378F003DDC24 /* PreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesStorage.swift; sourceTree = ""; }; + C4EEE46528DB3790003DDC24 /* FileOperator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileOperator.swift; sourceTree = ""; }; + C4EEE46628DB3790003DDC24 /* FileStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileStorage.swift; sourceTree = ""; }; + C4EEE47528DB3938003DDC24 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + C4EEE47F28DB39F1003DDC24 /* Note+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Note+CoreDataClass.swift"; sourceTree = ""; }; + C4EEE48028DB39F1003DDC24 /* Note+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Note+CoreDataProperties.swift"; sourceTree = ""; }; + C4EEE48328DB3B6B003DDC24 /* CoreDataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataStorage.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - C41A31BF28C49B310019B951 /* Frameworks */ = { + C4EEE41828DB33D8003DDC24 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C4EEE47628DB3938003DDC24 /* CoreData.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - C41A31D828C49B320019B951 /* Frameworks */ = { + C4EEE43128DB33D9003DDC24 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - C41A31E228C49B320019B951 /* Frameworks */ = { + C4EEE43B28DB33D9003DDC24 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -91,83 +98,102 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - C41A31B928C49B310019B951 = { + C4EEE41228DB33D8003DDC24 = { isa = PBXGroup; children = ( - C41A31C428C49B310019B951 /* Notes */, - C41A31DE28C49B320019B951 /* NotesTests */, - C41A31E828C49B320019B951 /* NotesUITests */, - C41A31C328C49B310019B951 /* Products */, + C4EEE41D28DB33D8003DDC24 /* Notes */, + C4EEE43728DB33D9003DDC24 /* NotesTests */, + C4EEE44128DB33D9003DDC24 /* NotesUITests */, + C4EEE41C28DB33D8003DDC24 /* Products */, + C4EEE47428DB3938003DDC24 /* Frameworks */, ); sourceTree = ""; }; - C41A31C328C49B310019B951 /* Products */ = { + C4EEE41C28DB33D8003DDC24 /* Products */ = { isa = PBXGroup; children = ( - C41A31C228C49B310019B951 /* Notes.app */, - C41A31DB28C49B320019B951 /* NotesTests.xctest */, - C41A31E528C49B320019B951 /* NotesUITests.xctest */, + C4EEE41B28DB33D8003DDC24 /* Notes.app */, + C4EEE43428DB33D9003DDC24 /* NotesTests.xctest */, + C4EEE43E28DB33D9003DDC24 /* NotesUITests.xctest */, ); name = Products; sourceTree = ""; }; - C41A31C428C49B310019B951 /* Notes */ = { + C4EEE41D28DB33D8003DDC24 /* Notes */ = { isa = PBXGroup; children = ( - C43417F128D4AACD0098C15A /* Notes.entitlements */, - C41A31C528C49B310019B951 /* AppDelegate.swift */, - C41A31C728C49B310019B951 /* SceneDelegate.swift */, - C41A31C928C49B310019B951 /* ViewController.swift */, - C41A31F828C49DC80019B951 /* NoteViewController.swift */, - C4EEE40628D89C46003DDC24 /* UIViewController+Extensions.swift */, - C43417F228D4AD9C0098C15A /* Storage */, - C41A31CB28C49B310019B951 /* Main.storyboard */, - C41A31D128C49B320019B951 /* Assets.xcassets */, - C41A31D328C49B320019B951 /* LaunchScreen.storyboard */, - C41A31D628C49B320019B951 /* Info.plist */, - C41A31CE28C49B310019B951 /* Notes.xcdatamodeld */, + C4EEE45928DB358A003DDC24 /* Notes.entitlements */, + C4EEE41E28DB33D8003DDC24 /* AppDelegate.swift */, + C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */, + C4EEE42228DB33D8003DDC24 /* ViewController.swift */, + C4EEE45128DB3422003DDC24 /* NoteViewController.swift */, + C4EEE45228DB3423003DDC24 /* UIViewController+Extensions.swift */, + C4EEE46B28DB379B003DDC24 /* Storage */, + C4EEE46228DB3714003DDC24 /* Model */, + C4EEE42428DB33D8003DDC24 /* Main.storyboard */, + C4EEE42A28DB33D9003DDC24 /* Assets.xcassets */, + C4EEE42C28DB33D9003DDC24 /* LaunchScreen.storyboard */, + C4EEE42F28DB33D9003DDC24 /* Info.plist */, + C4EEE42728DB33D8003DDC24 /* Notes.xcdatamodeld */, ); path = Notes; sourceTree = ""; }; - C41A31DE28C49B320019B951 /* NotesTests */ = { + C4EEE43728DB33D9003DDC24 /* NotesTests */ = { isa = PBXGroup; children = ( - C41A31DF28C49B320019B951 /* NotesTests.swift */, + C4EEE43828DB33D9003DDC24 /* NotesTests.swift */, ); path = NotesTests; sourceTree = ""; }; - C41A31E828C49B320019B951 /* NotesUITests */ = { + C4EEE44128DB33D9003DDC24 /* NotesUITests */ = { isa = PBXGroup; children = ( - C41A31E928C49B320019B951 /* NotesUITests.swift */, - C41A31EB28C49B320019B951 /* NotesUITestsLaunchTests.swift */, + C4EEE44228DB33D9003DDC24 /* NotesUITests.swift */, + C4EEE44428DB33D9003DDC24 /* NotesUITestsLaunchTests.swift */, ); path = NotesUITests; sourceTree = ""; }; - C43417F228D4AD9C0098C15A /* Storage */ = { + C4EEE46228DB3714003DDC24 /* Model */ = { isa = PBXGroup; children = ( - C41A31FA28C4D8040019B951 /* PreferencesStorage.swift */, - C43417F328D4ADB10098C15A /* FileOperator.swift */, - C43417F528D4ADDB0098C15A /* FileStorage.swift */, - C43417F928D4B9370098C15A /* Document.swift */, + C4EEE47F28DB39F1003DDC24 /* Note+CoreDataClass.swift */, + C4EEE48028DB39F1003DDC24 /* Note+CoreDataProperties.swift */, + ); + path = Model; + sourceTree = ""; + }; + C4EEE46B28DB379B003DDC24 /* Storage */ = { + isa = PBXGroup; + children = ( + C4EEE46528DB3790003DDC24 /* FileOperator.swift */, + C4EEE46628DB3790003DDC24 /* FileStorage.swift */, + C4EEE46428DB378F003DDC24 /* PreferencesStorage.swift */, + C4EEE48328DB3B6B003DDC24 /* CoreDataStorage.swift */, ); path = Storage; sourceTree = ""; }; + C4EEE47428DB3938003DDC24 /* Frameworks */ = { + isa = PBXGroup; + children = ( + C4EEE47528DB3938003DDC24 /* CoreData.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - C41A31C128C49B310019B951 /* Notes */ = { + C4EEE41A28DB33D8003DDC24 /* Notes */ = { isa = PBXNativeTarget; - buildConfigurationList = C41A31EF28C49B320019B951 /* Build configuration list for PBXNativeTarget "Notes" */; + buildConfigurationList = C4EEE44828DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "Notes" */; buildPhases = ( - C41A31BE28C49B310019B951 /* Sources */, - C41A31BF28C49B310019B951 /* Frameworks */, - C41A31C028C49B310019B951 /* Resources */, + C4EEE41728DB33D8003DDC24 /* Sources */, + C4EEE41828DB33D8003DDC24 /* Frameworks */, + C4EEE41928DB33D8003DDC24 /* Resources */, ); buildRules = ( ); @@ -175,107 +201,107 @@ ); name = Notes; productName = Notes; - productReference = C41A31C228C49B310019B951 /* Notes.app */; + productReference = C4EEE41B28DB33D8003DDC24 /* Notes.app */; productType = "com.apple.product-type.application"; }; - C41A31DA28C49B320019B951 /* NotesTests */ = { + C4EEE43328DB33D9003DDC24 /* NotesTests */ = { isa = PBXNativeTarget; - buildConfigurationList = C41A31F228C49B320019B951 /* Build configuration list for PBXNativeTarget "NotesTests" */; + buildConfigurationList = C4EEE44B28DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "NotesTests" */; buildPhases = ( - C41A31D728C49B320019B951 /* Sources */, - C41A31D828C49B320019B951 /* Frameworks */, - C41A31D928C49B320019B951 /* Resources */, + C4EEE43028DB33D9003DDC24 /* Sources */, + C4EEE43128DB33D9003DDC24 /* Frameworks */, + C4EEE43228DB33D9003DDC24 /* Resources */, ); buildRules = ( ); dependencies = ( - C41A31DD28C49B320019B951 /* PBXTargetDependency */, + C4EEE43628DB33D9003DDC24 /* PBXTargetDependency */, ); name = NotesTests; productName = NotesTests; - productReference = C41A31DB28C49B320019B951 /* NotesTests.xctest */; + productReference = C4EEE43428DB33D9003DDC24 /* NotesTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - C41A31E428C49B320019B951 /* NotesUITests */ = { + C4EEE43D28DB33D9003DDC24 /* NotesUITests */ = { isa = PBXNativeTarget; - buildConfigurationList = C41A31F528C49B320019B951 /* Build configuration list for PBXNativeTarget "NotesUITests" */; + buildConfigurationList = C4EEE44E28DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "NotesUITests" */; buildPhases = ( - C41A31E128C49B320019B951 /* Sources */, - C41A31E228C49B320019B951 /* Frameworks */, - C41A31E328C49B320019B951 /* Resources */, + C4EEE43A28DB33D9003DDC24 /* Sources */, + C4EEE43B28DB33D9003DDC24 /* Frameworks */, + C4EEE43C28DB33D9003DDC24 /* Resources */, ); buildRules = ( ); dependencies = ( - C41A31E728C49B320019B951 /* PBXTargetDependency */, + C4EEE44028DB33D9003DDC24 /* PBXTargetDependency */, ); name = NotesUITests; productName = NotesUITests; - productReference = C41A31E528C49B320019B951 /* NotesUITests.xctest */; + productReference = C4EEE43E28DB33D9003DDC24 /* NotesUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - C41A31BA28C49B310019B951 /* Project object */ = { + C4EEE41328DB33D8003DDC24 /* Project object */ = { isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1340; - LastUpgradeCheck = 1340; + LastSwiftUpdateCheck = 1400; + LastUpgradeCheck = 1400; TargetAttributes = { - C41A31C128C49B310019B951 = { - CreatedOnToolsVersion = 13.4.1; + C4EEE41A28DB33D8003DDC24 = { + CreatedOnToolsVersion = 14.0; }; - C41A31DA28C49B320019B951 = { - CreatedOnToolsVersion = 13.4.1; - TestTargetID = C41A31C128C49B310019B951; + C4EEE43328DB33D9003DDC24 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = C4EEE41A28DB33D8003DDC24; }; - C41A31E428C49B320019B951 = { - CreatedOnToolsVersion = 13.4.1; - TestTargetID = C41A31C128C49B310019B951; + C4EEE43D28DB33D9003DDC24 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = C4EEE41A28DB33D8003DDC24; }; }; }; - buildConfigurationList = C41A31BD28C49B310019B951 /* Build configuration list for PBXProject "Notes" */; - compatibilityVersion = "Xcode 13.0"; + buildConfigurationList = C4EEE41628DB33D8003DDC24 /* Build configuration list for PBXProject "Notes" */; + compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); - mainGroup = C41A31B928C49B310019B951; - productRefGroup = C41A31C328C49B310019B951 /* Products */; + mainGroup = C4EEE41228DB33D8003DDC24; + productRefGroup = C4EEE41C28DB33D8003DDC24 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - C41A31C128C49B310019B951 /* Notes */, - C41A31DA28C49B320019B951 /* NotesTests */, - C41A31E428C49B320019B951 /* NotesUITests */, + C4EEE41A28DB33D8003DDC24 /* Notes */, + C4EEE43328DB33D9003DDC24 /* NotesTests */, + C4EEE43D28DB33D9003DDC24 /* NotesUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - C41A31C028C49B310019B951 /* Resources */ = { + C4EEE41928DB33D8003DDC24 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C41A31D528C49B320019B951 /* LaunchScreen.storyboard in Resources */, - C41A31D228C49B320019B951 /* Assets.xcassets in Resources */, - C41A31CD28C49B310019B951 /* Main.storyboard in Resources */, + C4EEE42E28DB33D9003DDC24 /* LaunchScreen.storyboard in Resources */, + C4EEE42B28DB33D9003DDC24 /* Assets.xcassets in Resources */, + C4EEE42628DB33D8003DDC24 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C41A31D928C49B320019B951 /* Resources */ = { + C4EEE43228DB33D9003DDC24 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - C41A31E328C49B320019B951 /* Resources */ = { + C4EEE43C28DB33D9003DDC24 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -285,68 +311,70 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - C41A31BE28C49B310019B951 /* Sources */ = { + C4EEE41728DB33D8003DDC24 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C41A31CA28C49B310019B951 /* ViewController.swift in Sources */, - C41A31C628C49B310019B951 /* AppDelegate.swift in Sources */, - C4EEE40728D89C46003DDC24 /* UIViewController+Extensions.swift in Sources */, - C41A31FB28C4D8040019B951 /* PreferencesStorage.swift in Sources */, - C41A31C828C49B310019B951 /* SceneDelegate.swift in Sources */, - C43417F428D4ADB10098C15A /* FileOperator.swift in Sources */, - C43417FA28D4B9370098C15A /* Document.swift in Sources */, - C43417F628D4ADDB0098C15A /* FileStorage.swift in Sources */, - C41A31F928C49DC80019B951 /* NoteViewController.swift in Sources */, - C41A31D028C49B310019B951 /* Notes.xcdatamodeld in Sources */, + C4EEE48428DB3B6B003DDC24 /* CoreDataStorage.swift in Sources */, + C4EEE48228DB39F1003DDC24 /* Note+CoreDataProperties.swift in Sources */, + C4EEE46A28DB3790003DDC24 /* PreferencesStorage.swift in Sources */, + C4EEE42328DB33D8003DDC24 /* ViewController.swift in Sources */, + C4EEE46928DB3790003DDC24 /* FileStorage.swift in Sources */, + C4EEE41F28DB33D8003DDC24 /* AppDelegate.swift in Sources */, + C4EEE42128DB33D8003DDC24 /* SceneDelegate.swift in Sources */, + C4EEE45328DB3423003DDC24 /* NoteViewController.swift in Sources */, + C4EEE46728DB3790003DDC24 /* FileOperator.swift in Sources */, + C4EEE48128DB39F1003DDC24 /* Note+CoreDataClass.swift in Sources */, + C4EEE45428DB3423003DDC24 /* UIViewController+Extensions.swift in Sources */, + C4EEE42928DB33D8003DDC24 /* Notes.xcdatamodeld in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C41A31D728C49B320019B951 /* Sources */ = { + C4EEE43028DB33D9003DDC24 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C41A31E028C49B320019B951 /* NotesTests.swift in Sources */, + C4EEE43928DB33D9003DDC24 /* NotesTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C41A31E128C49B320019B951 /* Sources */ = { + C4EEE43A28DB33D9003DDC24 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C41A31EC28C49B320019B951 /* NotesUITestsLaunchTests.swift in Sources */, - C41A31EA28C49B320019B951 /* NotesUITests.swift in Sources */, + C4EEE44528DB33D9003DDC24 /* NotesUITestsLaunchTests.swift in Sources */, + C4EEE44328DB33D9003DDC24 /* NotesUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - C41A31DD28C49B320019B951 /* PBXTargetDependency */ = { + C4EEE43628DB33D9003DDC24 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C41A31C128C49B310019B951 /* Notes */; - targetProxy = C41A31DC28C49B320019B951 /* PBXContainerItemProxy */; + target = C4EEE41A28DB33D8003DDC24 /* Notes */; + targetProxy = C4EEE43528DB33D9003DDC24 /* PBXContainerItemProxy */; }; - C41A31E728C49B320019B951 /* PBXTargetDependency */ = { + C4EEE44028DB33D9003DDC24 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C41A31C128C49B310019B951 /* Notes */; - targetProxy = C41A31E628C49B320019B951 /* PBXContainerItemProxy */; + target = C4EEE41A28DB33D8003DDC24 /* Notes */; + targetProxy = C4EEE43F28DB33D9003DDC24 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - C41A31CB28C49B310019B951 /* Main.storyboard */ = { + C4EEE42428DB33D8003DDC24 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( - C41A31CC28C49B310019B951 /* Base */, + C4EEE42528DB33D8003DDC24 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; - C41A31D328C49B320019B951 /* LaunchScreen.storyboard */ = { + C4EEE42C28DB33D9003DDC24 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - C41A31D428C49B320019B951 /* Base */, + C4EEE42D28DB33D9003DDC24 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; @@ -354,13 +382,13 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - C41A31ED28C49B320019B951 /* Debug */ = { + C4EEE44628DB33D9003DDC24 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; @@ -414,13 +442,13 @@ }; name = Debug; }; - C41A31EE28C49B320019B951 /* Release */ = { + C4EEE44728DB33D9003DDC24 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; @@ -468,12 +496,11 @@ }; name = Release; }; - C41A31F028C49B320019B951 /* Debug */ = { + C4EEE44928DB33D9003DDC24 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = Notes/Notes.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; @@ -483,7 +510,6 @@ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -499,12 +525,11 @@ }; name = Debug; }; - C41A31F128C49B320019B951 /* Release */ = { + C4EEE44A28DB33D9003DDC24 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_ENTITLEMENTS = Notes/Notes.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; @@ -514,7 +539,6 @@ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -530,7 +554,7 @@ }; name = Release; }; - C41A31F328C49B320019B951 /* Debug */ = { + C4EEE44C28DB33D9003DDC24 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; @@ -539,18 +563,18 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 526E96RFNP; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.5; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.NotesTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Notes.app/Notes"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Notes.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Notes"; }; name = Debug; }; - C41A31F428C49B320019B951 /* Release */ = { + C4EEE44D28DB33D9003DDC24 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; @@ -559,18 +583,18 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 526E96RFNP; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.5; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.NotesTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Notes.app/Notes"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Notes.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Notes"; }; name = Release; }; - C41A31F628C49B320019B951 /* Debug */ = { + C4EEE44F28DB33D9003DDC24 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; @@ -588,7 +612,7 @@ }; name = Debug; }; - C41A31F728C49B320019B951 /* Release */ = { + C4EEE45028DB33D9003DDC24 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; @@ -609,38 +633,38 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - C41A31BD28C49B310019B951 /* Build configuration list for PBXProject "Notes" */ = { + C4EEE41628DB33D8003DDC24 /* Build configuration list for PBXProject "Notes" */ = { isa = XCConfigurationList; buildConfigurations = ( - C41A31ED28C49B320019B951 /* Debug */, - C41A31EE28C49B320019B951 /* Release */, + C4EEE44628DB33D9003DDC24 /* Debug */, + C4EEE44728DB33D9003DDC24 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C41A31EF28C49B320019B951 /* Build configuration list for PBXNativeTarget "Notes" */ = { + C4EEE44828DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "Notes" */ = { isa = XCConfigurationList; buildConfigurations = ( - C41A31F028C49B320019B951 /* Debug */, - C41A31F128C49B320019B951 /* Release */, + C4EEE44928DB33D9003DDC24 /* Debug */, + C4EEE44A28DB33D9003DDC24 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C41A31F228C49B320019B951 /* Build configuration list for PBXNativeTarget "NotesTests" */ = { + C4EEE44B28DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "NotesTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - C41A31F328C49B320019B951 /* Debug */, - C41A31F428C49B320019B951 /* Release */, + C4EEE44C28DB33D9003DDC24 /* Debug */, + C4EEE44D28DB33D9003DDC24 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C41A31F528C49B320019B951 /* Build configuration list for PBXNativeTarget "NotesUITests" */ = { + C4EEE44E28DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "NotesUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( - C41A31F628C49B320019B951 /* Debug */, - C41A31F728C49B320019B951 /* Release */, + C4EEE44F28DB33D9003DDC24 /* Debug */, + C4EEE45028DB33D9003DDC24 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -648,17 +672,17 @@ /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ - C41A31CE28C49B310019B951 /* Notes.xcdatamodeld */ = { + C4EEE42728DB33D8003DDC24 /* Notes.xcdatamodeld */ = { isa = XCVersionGroup; children = ( - C41A31CF28C49B310019B951 /* Notes.xcdatamodel */, + C4EEE42828DB33D8003DDC24 /* Notes.xcdatamodel */, ); - currentVersion = C41A31CF28C49B310019B951 /* Notes.xcdatamodel */; + currentVersion = C4EEE42828DB33D8003DDC24 /* Notes.xcdatamodel */; path = Notes.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; }; /* End XCVersionGroup section */ }; - rootObject = C41A31BA28C49B310019B951 /* Project object */; + rootObject = C4EEE41328DB33D8003DDC24 /* Project object */; } diff --git a/Notes/AppDelegate.swift b/Notes/AppDelegate.swift index 8bcf003..68054c9 100644 --- a/Notes/AppDelegate.swift +++ b/Notes/AppDelegate.swift @@ -2,7 +2,7 @@ // AppDelegate.swift // Notes // -// Created by Laurent Morvillier on 04/09/2022. +// Created by Laurent Morvillier on 21/09/2022. // import UIKit @@ -11,23 +11,20 @@ import CoreData @main class AppDelegate: UIResponder, UIApplicationDelegate { + static var shared: AppDelegate { + return UIApplication.shared.delegate as! AppDelegate + } + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - -// let fn = "main" -// if let content = PreferencesStorage.main.getContent(filename: fn) { -// FileStorage.main.requestStorage(filename: "main.txt", content: content) -// } + if let content = PreferencesStorage.main.getContent(filename: "main.txt") { + let note = Note(context: AppDelegate.viewContext) + note.content = content + AppDelegate.shared.saveContext() + print("default note created") + } -// for fontFamilyName in UIFont.familyNames { -// print("family: \(fontFamilyName)\n") -// -// for fontName in UIFont.fontNames(forFamilyName: fontFamilyName) { -// print("font: \(fontName)") -// } -// } - + // Override point for customization after application launch. return true } @@ -75,8 +72,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { }() // MARK: - Core Data Saving support - + + static var viewContext: NSManagedObjectContext { + return self.shared.persistentContainer.viewContext + } + func saveContext () { + print("save context...") let context = persistentContainer.viewContext if context.hasChanges { do { diff --git a/Notes/Info.plist b/Notes/Info.plist index dd3c9af..581b5fd 100644 --- a/Notes/Info.plist +++ b/Notes/Info.plist @@ -21,5 +21,9 @@ + UIBackgroundModes + + remote-notification + diff --git a/Notes/Model/Note+CoreDataClass.swift b/Notes/Model/Note+CoreDataClass.swift new file mode 100644 index 0000000..20629a0 --- /dev/null +++ b/Notes/Model/Note+CoreDataClass.swift @@ -0,0 +1,15 @@ +// +// Note+CoreDataClass.swift +// Notes +// +// Created by Laurent Morvillier on 21/09/2022. +// +// + +import Foundation +import CoreData + + +public class Note: NSManagedObject { + +} diff --git a/Notes/Model/Note+CoreDataProperties.swift b/Notes/Model/Note+CoreDataProperties.swift new file mode 100644 index 0000000..53d4377 --- /dev/null +++ b/Notes/Model/Note+CoreDataProperties.swift @@ -0,0 +1,27 @@ +// +// Note+CoreDataProperties.swift +// Notes +// +// Created by Laurent Morvillier on 21/09/2022. +// +// + +import Foundation +import CoreData + + +extension Note { + + @nonobjc public class func fetchRequest() -> NSFetchRequest { + return NSFetchRequest(entityName: "Note") + } + + @NSManaged public var content: String? + @NSManaged public var title: String? + @NSManaged public var lastEditDate: Date? + +} + +extension Note : Identifiable { + +} diff --git a/Notes/NoteViewController.swift b/Notes/NoteViewController.swift index e8aa05c..fcff952 100644 --- a/Notes/NoteViewController.swift +++ b/Notes/NoteViewController.swift @@ -10,7 +10,7 @@ import UIKit class NoteViewController : UIViewController, UITextViewDelegate { - var filename: String = "main.txt" + var note: Note? = nil @IBOutlet weak var textView: UITextView! @@ -27,11 +27,7 @@ class NoteViewController : UIViewController, UITextViewDelegate { let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addHandler)) self.navigationItem.rightBarButtonItems = [addButton, shareButton] - do { - self.textView.text = try FileStorage.main.getContent(filename: self.filename) - } catch { - self.showAlert(message: error.localizedDescription, title: "Error :(") - } + self._loadLastNote() self.textView.font = UIFont.systemFont(ofSize: 18.0, weight: .regular) self.textView.delegate = self @@ -39,6 +35,12 @@ class NoteViewController : UIViewController, UITextViewDelegate { self._updateLastEdit() + /// Store notifications + + NotificationCenter.default.addObserver(self, selector: #selector(self._storeRemoteChange(notification:)), name: .NSPersistentStoreCoordinatorStoresDidChange, object: nil) + + /// Keyboard notifications + NotificationCenter.default.addObserver( self, selector: #selector(keyboardDidShow(notification:)), @@ -55,14 +57,44 @@ class NoteViewController : UIViewController, UITextViewDelegate { } + fileprivate func _loadLastNote() { + + let request = Note.fetchRequest() + request.sortDescriptors = [NSSortDescriptor(key: "lastEditDate", ascending: false)] + + do { + self.note = try AppDelegate.viewContext.fetch(request).first + self.textView.text = self.note?.content + } catch { + print("Fetch error = \(error)") + } + + } + + @objc fileprivate func _storeRemoteChange(notification: Notification) { + print("_storeRemoteChange...") + self._loadLastNote() + } + func textViewDidChange(_ textView: UITextView) { - FileStorage.main.requestStorage(filename: self.filename, content: textView.text) + PreferencesStorage.main.requestStorage(filename: "main.txt", content: textView.text) + + let note: Note + if let n = self.note { + note = n + } else { + note = Note(context: AppDelegate.viewContext) + self.note = note + } + + CoreDataStorage.main.requestStorage(note: note, content: textView.text) + self._updateLastEdit() } fileprivate func _updateLastEdit() { - if let date = try? FileStorage.main.lastEditDate(filename: self.filename) { + if let date = self.note?.lastEditDate { let formattedDate: String = date.formatted() self._lastEditLabel?.text = "last edit: \(formattedDate)" } diff --git a/Notes/Notes.entitlements b/Notes/Notes.entitlements index 1d888bd..68b002a 100644 --- a/Notes/Notes.entitlements +++ b/Notes/Notes.entitlements @@ -2,13 +2,15 @@ + aps-environment + development com.apple.developer.icloud-container-identifiers - + + iCloud.com.staxriver.Note + com.apple.developer.icloud-services - CloudDocuments + CloudKit - com.apple.developer.ubiquity-container-identifiers - diff --git a/Notes/Notes.xcdatamodeld/Notes.xcdatamodel/contents b/Notes/Notes.xcdatamodeld/Notes.xcdatamodel/contents index 23c0b10..6e65dc5 100644 --- a/Notes/Notes.xcdatamodeld/Notes.xcdatamodel/contents +++ b/Notes/Notes.xcdatamodeld/Notes.xcdatamodel/contents @@ -1,4 +1,8 @@ - - + + + + + + \ No newline at end of file diff --git a/Notes/SceneDelegate.swift b/Notes/SceneDelegate.swift index c25a91f..25fb5f7 100644 --- a/Notes/SceneDelegate.swift +++ b/Notes/SceneDelegate.swift @@ -2,7 +2,7 @@ // SceneDelegate.swift // Notes // -// Created by Laurent Morvillier on 04/09/2022. +// Created by Laurent Morvillier on 21/09/2022. // import UIKit diff --git a/Notes/Storage/CoreDataStorage.swift b/Notes/Storage/CoreDataStorage.swift new file mode 100644 index 0000000..0290126 --- /dev/null +++ b/Notes/Storage/CoreDataStorage.swift @@ -0,0 +1,30 @@ +// +// CoreDataStorage.swift +// Notes +// +// Created by Laurent Morvillier on 21/09/2022. +// + +import Foundation + +class CoreDataStorage { + + static var main: CoreDataStorage = CoreDataStorage() + + fileprivate var _timer: Timer? = nil + + func requestStorage(note: Note, content: String) { + + note.content = content + note.lastEditDate = Date() + + self._timer?.invalidate() + self._timer = Timer.scheduledTimer(timeInterval: idleTimeBeforeSaving, target: self, selector: #selector(self._storageRequested), userInfo: nil, repeats: false) + + } + + @objc fileprivate func _storageRequested() { + AppDelegate.shared.saveContext() + } + +} diff --git a/Notes/Storage/Document.swift b/Notes/Storage/Document.swift deleted file mode 100644 index be4d6f5..0000000 --- a/Notes/Storage/Document.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// Document.swift -// Notes -// -// Created by Laurent Morvillier on 16/09/2022. -// - -import Foundation -import UIKit - -class Document : UIDocument { - -} diff --git a/Notes/Storage/FileStorage.swift b/Notes/Storage/FileStorage.swift index 7bdf7b9..01268f3 100644 --- a/Notes/Storage/FileStorage.swift +++ b/Notes/Storage/FileStorage.swift @@ -15,6 +15,14 @@ struct StorageRequest { let idleTimeBeforeSaving = 2.0 +fileprivate extension NSMetadataItem { + + var url: URL? { + return self.value(forAttribute: NSMetadataItemURLKey) as? URL + } + +} + /// Should we have a way to go from local to iCloud? /// https://stackoverflow.com/questions/33886846/best-way-to-use-icloud-documents-storage /// Should we store the files locally whatever the iCloud choice is? @@ -22,21 +30,32 @@ class FileStorage : FileOperator { static var main: FileStorage = FileStorage() - fileprivate var _containerURL: URL? + fileprivate var _cloudContainerURL: URL? fileprivate var _cloudStorageDetermined: Bool = false + fileprivate let containerTeamId = "notes" fileprivate let containerIdentifier = "notes" fileprivate var _timer: Timer? = nil + fileprivate var _downloadTimer: Timer? = nil + + fileprivate var _downloads: [NSMetadataItem] = [] fileprivate var _storageRequests: [String : String] = [:] init() { + + let uit = FileManager.default.ubiquityIdentityToken + print("ubiquityIdentityToken = \(String(describing: uit))") + DispatchQueue.global(qos: .userInteractive).async { - self._containerURL = FileManager.default.url(forUbiquityContainerIdentifier: self.containerIdentifier) + self._cloudContainerURL = FileManager.default.url(forUbiquityContainerIdentifier: nil) self._cloudStorageDetermined = true - print("Cloud container URL is : \(String(describing: self._containerURL?.absoluteString))") + print("Cloud container URL is : \(String(describing: self._cloudContainerURL?.absoluteString))") + +// self._makeLocalCopyIfNecessary() + } } @@ -45,6 +64,87 @@ class FileStorage : FileOperator { return documentDirectory } + fileprivate func _makeLocalCopyIfNecessary() { + + // if the local dir is not empty, do nothing + if let docDir = try? self._directoryURL(), let files = try? FileManager.default.contentsOfDirectory(atPath: docDir.absoluteString), files.count > 0 { + return + } + + guard let _ = self._cloudContainerURL else { + return + } + + NotificationCenter.default.addObserver(self, selector: #selector(metaDataQueryNotified(notification:)), name: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: nil) + + let query = NSMetadataQuery() + query.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope] + query.start() + + } + + @objc func metaDataQueryNotified(notification: Notification) { + + guard let query = notification.object as? NSMetadataQuery else { + print("object = \(notification.object ?? "")") + return + } + + for case let item as NSMetadataItem in query.results { + + if let url = item.value(forAttribute: NSMetadataItemURLKey) as? URL { + self._downloadItem(item, url: url) + } else { + print("item has no URL") + } + } + } + + + fileprivate func _downloadItem(_ item: NSMetadataItem, url: URL) { + do { + try FileManager.default.startDownloadingUbiquitousItem(at: url) + self._startStatusTimer(item: item) + } catch { + print("error = \(error)") + } + } + + fileprivate func _startStatusTimer(item: NSMetadataItem) { + self._downloads.append(item) + if self._downloadTimer == nil { + self._downloadTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self._verifyDownloadStatus), userInfo: nil, repeats: false) + } + } + + @objc fileprivate func _verifyDownloadStatus() { + + let downloads = Array(self._downloads) + + for item in downloads { + if item.value(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? String == NSMetadataUbiquitousItemDownloadingStatusCurrent { + + self._makeLocalCopy(item: item) + self._downloads.removeAll(where: { $0.url == item.url }) + } + } + + } + + fileprivate func _makeLocalCopy(item: NSMetadataItem) { + + guard let fileURL = item.url, let docURL = try? self._directoryURL() else { + return + } + + do { + try FileManager.default.copyItem(at: fileURL, to: docURL) + } catch { + print("error: \(error)") // TODO + } + + } + // MARK: - FileOperator func requestStorage(filename: String, content: String) { @@ -90,12 +190,18 @@ class FileStorage : FileOperator { } fileprivate func _copyToCloudContainerIfNecessary(fileURL: URL, filename: String) throws { - guard let containerURL = self._containerURL else { + guard let containerURL = self._cloudContainerURL else { + print("cloud container is nil, stays local") return } let cloudURL = containerURL.appending(path: filename) + print("cloud copy to: \(cloudURL)...") + +// if FileManager.default.fileExists(atPath: cloudURL.absoluteString) { +// try FileManager.default.removeItem(at: cloudURL) +// } + try FileManager.default.copyItem(at: fileURL, to: cloudURL) - print("cloud copy to: \(cloudURL)") } deinit { diff --git a/Notes/Storage/PreferencesStorage.swift b/Notes/Storage/PreferencesStorage.swift index 75b9969..a3fe06e 100644 --- a/Notes/Storage/PreferencesStorage.swift +++ b/Notes/Storage/PreferencesStorage.swift @@ -7,25 +7,25 @@ import Foundation -//class PreferencesStorage : FileOperator { -// -// static var main = PreferencesStorage() -// -// func requestStorage(filename: String, content: String) { -// UserDefaults.standard.set(content, forKey: filename) -// PreferencesStorage._fileChanged(filename: filename) -// } -// -// fileprivate static func _fileChanged(filename: String) { -// UserDefaults.standard.set(Date(), forKey: filename + "_date") -// } -// -// func getContent(filename: String) -> String? { -// return UserDefaults.standard.object(forKey: filename) as? String -// } -// -// func lastEditDate(filename: String) -> Date? { -// return UserDefaults.standard.object(forKey: filename + "_date") as? Date -// } -// -//} +class PreferencesStorage : FileOperator { + + static var main = PreferencesStorage() + + func requestStorage(filename: String, content: String) { + UserDefaults.standard.set(content, forKey: filename) + PreferencesStorage._fileChanged(filename: filename) + } + + fileprivate static func _fileChanged(filename: String) { + UserDefaults.standard.set(Date(), forKey: filename + "_date") + } + + func getContent(filename: String) -> String? { + return UserDefaults.standard.object(forKey: filename) as? String + } + + func lastEditDate(filename: String) -> Date? { + return UserDefaults.standard.object(forKey: filename + "_date") as? Date + } + +} diff --git a/Notes/ViewController.swift b/Notes/ViewController.swift index 176169a..11fb1e8 100644 --- a/Notes/ViewController.swift +++ b/Notes/ViewController.swift @@ -2,7 +2,7 @@ // ViewController.swift // Notes // -// Created by Laurent Morvillier on 04/09/2022. +// Created by Laurent Morvillier on 21/09/2022. // import UIKit diff --git a/NotesTests/NotesTests.swift b/NotesTests/NotesTests.swift index 6b14d36..1b933ac 100644 --- a/NotesTests/NotesTests.swift +++ b/NotesTests/NotesTests.swift @@ -2,13 +2,13 @@ // NotesTests.swift // NotesTests // -// Created by Laurent Morvillier on 04/09/2022. +// Created by Laurent Morvillier on 21/09/2022. // import XCTest @testable import Notes -class NotesTests: XCTestCase { +final class NotesTests: XCTestCase { override func setUpWithError() throws { // Put setup code here. This method is called before the invocation of each test method in the class. diff --git a/NotesUITests/NotesUITests.swift b/NotesUITests/NotesUITests.swift index fff8f03..7ec5f40 100644 --- a/NotesUITests/NotesUITests.swift +++ b/NotesUITests/NotesUITests.swift @@ -2,12 +2,12 @@ // NotesUITests.swift // NotesUITests // -// Created by Laurent Morvillier on 04/09/2022. +// Created by Laurent Morvillier on 21/09/2022. // import XCTest -class NotesUITests: XCTestCase { +final class NotesUITests: XCTestCase { override func setUpWithError() throws { // Put setup code here. This method is called before the invocation of each test method in the class. diff --git a/NotesUITests/NotesUITestsLaunchTests.swift b/NotesUITests/NotesUITestsLaunchTests.swift index eebbd07..7abc6a7 100644 --- a/NotesUITests/NotesUITestsLaunchTests.swift +++ b/NotesUITests/NotesUITestsLaunchTests.swift @@ -2,12 +2,12 @@ // NotesUITestsLaunchTests.swift // NotesUITests // -// Created by Laurent Morvillier on 04/09/2022. +// Created by Laurent Morvillier on 21/09/2022. // import XCTest -class NotesUITestsLaunchTests: XCTestCase { +final class NotesUITestsLaunchTests: XCTestCase { override class var runsForEachTargetApplicationUIConfiguration: Bool { true diff --git a/README.md b/README.md deleted file mode 100644 index 8573797..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# notes - -application iOS de notes \ No newline at end of file