Cloudkit integration

main
Laurent 3 years ago
parent 76db659137
commit 7690ea7d8c
  1. 390
      Notes.xcodeproj/project.pbxproj
  2. 34
      Notes/AppDelegate.swift
  3. 4
      Notes/Info.plist
  4. 15
      Notes/Model/Note+CoreDataClass.swift
  5. 27
      Notes/Model/Note+CoreDataProperties.swift
  6. 48
      Notes/NoteViewController.swift
  7. 10
      Notes/Notes.entitlements
  8. 8
      Notes/Notes.xcdatamodeld/Notes.xcdatamodel/contents
  9. 2
      Notes/SceneDelegate.swift
  10. 30
      Notes/Storage/CoreDataStorage.swift
  11. 13
      Notes/Storage/Document.swift
  12. 116
      Notes/Storage/FileStorage.swift
  13. 44
      Notes/Storage/PreferencesStorage.swift
  14. 2
      Notes/ViewController.swift
  15. 4
      NotesTests/NotesTests.swift
  16. 4
      NotesUITests/NotesUITests.swift
  17. 4
      NotesUITests/NotesUITestsLaunchTests.swift
  18. 3
      README.md

@ -3,85 +3,92 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 55; objectVersion = 56;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
C41A31C628C49B310019B951 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31C528C49B310019B951 /* AppDelegate.swift */; }; C4EEE41F28DB33D8003DDC24 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE41E28DB33D8003DDC24 /* AppDelegate.swift */; };
C41A31C828C49B310019B951 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31C728C49B310019B951 /* SceneDelegate.swift */; }; C4EEE42128DB33D8003DDC24 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */; };
C41A31CA28C49B310019B951 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31C928C49B310019B951 /* ViewController.swift */; }; C4EEE42328DB33D8003DDC24 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE42228DB33D8003DDC24 /* ViewController.swift */; };
C41A31CD28C49B310019B951 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C41A31CB28C49B310019B951 /* Main.storyboard */; }; C4EEE42628DB33D8003DDC24 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C4EEE42428DB33D8003DDC24 /* Main.storyboard */; };
C41A31D028C49B310019B951 /* Notes.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C41A31CE28C49B310019B951 /* Notes.xcdatamodeld */; }; C4EEE42928DB33D8003DDC24 /* Notes.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE42728DB33D8003DDC24 /* Notes.xcdatamodeld */; };
C41A31D228C49B320019B951 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C41A31D128C49B320019B951 /* Assets.xcassets */; }; C4EEE42B28DB33D9003DDC24 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C4EEE42A28DB33D9003DDC24 /* Assets.xcassets */; };
C41A31D528C49B320019B951 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C41A31D328C49B320019B951 /* LaunchScreen.storyboard */; }; C4EEE42E28DB33D9003DDC24 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C4EEE42C28DB33D9003DDC24 /* LaunchScreen.storyboard */; };
C41A31E028C49B320019B951 /* NotesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31DF28C49B320019B951 /* NotesTests.swift */; }; C4EEE43928DB33D9003DDC24 /* NotesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE43828DB33D9003DDC24 /* NotesTests.swift */; };
C41A31EA28C49B320019B951 /* NotesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31E928C49B320019B951 /* NotesUITests.swift */; }; C4EEE44328DB33D9003DDC24 /* NotesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE44228DB33D9003DDC24 /* NotesUITests.swift */; };
C41A31EC28C49B320019B951 /* NotesUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31EB28C49B320019B951 /* NotesUITestsLaunchTests.swift */; }; C4EEE44528DB33D9003DDC24 /* NotesUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE44428DB33D9003DDC24 /* NotesUITestsLaunchTests.swift */; };
C41A31F928C49DC80019B951 /* NoteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31F828C49DC80019B951 /* NoteViewController.swift */; }; C4EEE45328DB3423003DDC24 /* NoteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE45128DB3422003DDC24 /* NoteViewController.swift */; };
C41A31FB28C4D8040019B951 /* PreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41A31FA28C4D8040019B951 /* PreferencesStorage.swift */; }; C4EEE45428DB3423003DDC24 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE45228DB3423003DDC24 /* UIViewController+Extensions.swift */; };
C43417F428D4ADB10098C15A /* FileOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43417F328D4ADB10098C15A /* FileOperator.swift */; }; C4EEE46728DB3790003DDC24 /* FileOperator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE46528DB3790003DDC24 /* FileOperator.swift */; };
C43417F628D4ADDB0098C15A /* FileStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43417F528D4ADDB0098C15A /* FileStorage.swift */; }; C4EEE46928DB3790003DDC24 /* FileStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE46628DB3790003DDC24 /* FileStorage.swift */; };
C43417FA28D4B9370098C15A /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43417F928D4B9370098C15A /* Document.swift */; }; C4EEE46A28DB3790003DDC24 /* PreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE46428DB378F003DDC24 /* PreferencesStorage.swift */; };
C4EEE40728D89C46003DDC24 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE40628D89C46003DDC24 /* UIViewController+Extensions.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 */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
C41A31DC28C49B320019B951 /* PBXContainerItemProxy */ = { C4EEE43528DB33D9003DDC24 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = C41A31BA28C49B310019B951 /* Project object */; containerPortal = C4EEE41328DB33D8003DDC24 /* Project object */;
proxyType = 1; proxyType = 1;
remoteGlobalIDString = C41A31C128C49B310019B951; remoteGlobalIDString = C4EEE41A28DB33D8003DDC24;
remoteInfo = Notes; remoteInfo = Notes;
}; };
C41A31E628C49B320019B951 /* PBXContainerItemProxy */ = { C4EEE43F28DB33D9003DDC24 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = C41A31BA28C49B310019B951 /* Project object */; containerPortal = C4EEE41328DB33D8003DDC24 /* Project object */;
proxyType = 1; proxyType = 1;
remoteGlobalIDString = C41A31C128C49B310019B951; remoteGlobalIDString = C4EEE41A28DB33D8003DDC24;
remoteInfo = Notes; remoteInfo = Notes;
}; };
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
C41A31C228C49B310019B951 /* Notes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Notes.app; sourceTree = BUILT_PRODUCTS_DIR; }; C4EEE41B28DB33D8003DDC24 /* 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 = "<group>"; }; C4EEE41E28DB33D8003DDC24 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C41A31C728C49B310019B951 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; }; C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
C41A31C928C49B310019B951 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; }; C4EEE42228DB33D8003DDC24 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
C41A31CC28C49B310019B951 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; C4EEE42528DB33D8003DDC24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
C41A31CF28C49B310019B951 /* Notes.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Notes.xcdatamodel; sourceTree = "<group>"; }; C4EEE42828DB33D8003DDC24 /* Notes.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Notes.xcdatamodel; sourceTree = "<group>"; };
C41A31D128C49B320019B951 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; C4EEE42A28DB33D9003DDC24 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
C41A31D428C49B320019B951 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; C4EEE42D28DB33D9003DDC24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
C41A31D628C49B320019B951 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; C4EEE42F28DB33D9003DDC24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C41A31DB28C49B320019B951 /* NotesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NotesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C4EEE43428DB33D9003DDC24 /* 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 = "<group>"; }; C4EEE43828DB33D9003DDC24 /* NotesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesTests.swift; sourceTree = "<group>"; };
C41A31E528C49B320019B951 /* NotesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NotesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C4EEE43E28DB33D9003DDC24 /* 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 = "<group>"; }; C4EEE44228DB33D9003DDC24 /* NotesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesUITests.swift; sourceTree = "<group>"; };
C41A31EB28C49B320019B951 /* NotesUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesUITestsLaunchTests.swift; sourceTree = "<group>"; }; C4EEE44428DB33D9003DDC24 /* NotesUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesUITestsLaunchTests.swift; sourceTree = "<group>"; };
C41A31F828C49DC80019B951 /* NoteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteViewController.swift; sourceTree = "<group>"; }; C4EEE45128DB3422003DDC24 /* NoteViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoteViewController.swift; sourceTree = "<group>"; };
C41A31FA28C4D8040019B951 /* PreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesStorage.swift; sourceTree = "<group>"; }; C4EEE45228DB3423003DDC24 /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extensions.swift"; sourceTree = "<group>"; };
C43417F128D4AACD0098C15A /* Notes.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Notes.entitlements; sourceTree = "<group>"; }; C4EEE45928DB358A003DDC24 /* Notes.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Notes.entitlements; sourceTree = "<group>"; };
C43417F328D4ADB10098C15A /* FileOperator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileOperator.swift; sourceTree = "<group>"; }; C4EEE46428DB378F003DDC24 /* PreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesStorage.swift; sourceTree = "<group>"; };
C43417F528D4ADDB0098C15A /* FileStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileStorage.swift; sourceTree = "<group>"; }; C4EEE46528DB3790003DDC24 /* FileOperator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileOperator.swift; sourceTree = "<group>"; };
C43417F928D4B9370098C15A /* Document.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Document.swift; sourceTree = "<group>"; }; C4EEE46628DB3790003DDC24 /* FileStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileStorage.swift; sourceTree = "<group>"; };
C4EEE40628D89C46003DDC24 /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extensions.swift"; sourceTree = "<group>"; }; 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 = "<group>"; };
C4EEE48028DB39F1003DDC24 /* Note+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Note+CoreDataProperties.swift"; sourceTree = "<group>"; };
C4EEE48328DB3B6B003DDC24 /* CoreDataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataStorage.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
C41A31BF28C49B310019B951 /* Frameworks */ = { C4EEE41828DB33D8003DDC24 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
C4EEE47628DB3938003DDC24 /* CoreData.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
C41A31D828C49B320019B951 /* Frameworks */ = { C4EEE43128DB33D9003DDC24 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
C41A31E228C49B320019B951 /* Frameworks */ = { C4EEE43B28DB33D9003DDC24 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -91,83 +98,102 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
C41A31B928C49B310019B951 = { C4EEE41228DB33D8003DDC24 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C41A31C428C49B310019B951 /* Notes */, C4EEE41D28DB33D8003DDC24 /* Notes */,
C41A31DE28C49B320019B951 /* NotesTests */, C4EEE43728DB33D9003DDC24 /* NotesTests */,
C41A31E828C49B320019B951 /* NotesUITests */, C4EEE44128DB33D9003DDC24 /* NotesUITests */,
C41A31C328C49B310019B951 /* Products */, C4EEE41C28DB33D8003DDC24 /* Products */,
C4EEE47428DB3938003DDC24 /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C41A31C328C49B310019B951 /* Products */ = { C4EEE41C28DB33D8003DDC24 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C41A31C228C49B310019B951 /* Notes.app */, C4EEE41B28DB33D8003DDC24 /* Notes.app */,
C41A31DB28C49B320019B951 /* NotesTests.xctest */, C4EEE43428DB33D9003DDC24 /* NotesTests.xctest */,
C41A31E528C49B320019B951 /* NotesUITests.xctest */, C4EEE43E28DB33D9003DDC24 /* NotesUITests.xctest */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C41A31C428C49B310019B951 /* Notes */ = { C4EEE41D28DB33D8003DDC24 /* Notes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C43417F128D4AACD0098C15A /* Notes.entitlements */, C4EEE45928DB358A003DDC24 /* Notes.entitlements */,
C41A31C528C49B310019B951 /* AppDelegate.swift */, C4EEE41E28DB33D8003DDC24 /* AppDelegate.swift */,
C41A31C728C49B310019B951 /* SceneDelegate.swift */, C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */,
C41A31C928C49B310019B951 /* ViewController.swift */, C4EEE42228DB33D8003DDC24 /* ViewController.swift */,
C41A31F828C49DC80019B951 /* NoteViewController.swift */, C4EEE45128DB3422003DDC24 /* NoteViewController.swift */,
C4EEE40628D89C46003DDC24 /* UIViewController+Extensions.swift */, C4EEE45228DB3423003DDC24 /* UIViewController+Extensions.swift */,
C43417F228D4AD9C0098C15A /* Storage */, C4EEE46B28DB379B003DDC24 /* Storage */,
C41A31CB28C49B310019B951 /* Main.storyboard */, C4EEE46228DB3714003DDC24 /* Model */,
C41A31D128C49B320019B951 /* Assets.xcassets */, C4EEE42428DB33D8003DDC24 /* Main.storyboard */,
C41A31D328C49B320019B951 /* LaunchScreen.storyboard */, C4EEE42A28DB33D9003DDC24 /* Assets.xcassets */,
C41A31D628C49B320019B951 /* Info.plist */, C4EEE42C28DB33D9003DDC24 /* LaunchScreen.storyboard */,
C41A31CE28C49B310019B951 /* Notes.xcdatamodeld */, C4EEE42F28DB33D9003DDC24 /* Info.plist */,
C4EEE42728DB33D8003DDC24 /* Notes.xcdatamodeld */,
); );
path = Notes; path = Notes;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C41A31DE28C49B320019B951 /* NotesTests */ = { C4EEE43728DB33D9003DDC24 /* NotesTests */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C41A31DF28C49B320019B951 /* NotesTests.swift */, C4EEE43828DB33D9003DDC24 /* NotesTests.swift */,
); );
path = NotesTests; path = NotesTests;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C41A31E828C49B320019B951 /* NotesUITests */ = { C4EEE44128DB33D9003DDC24 /* NotesUITests */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C41A31E928C49B320019B951 /* NotesUITests.swift */, C4EEE44228DB33D9003DDC24 /* NotesUITests.swift */,
C41A31EB28C49B320019B951 /* NotesUITestsLaunchTests.swift */, C4EEE44428DB33D9003DDC24 /* NotesUITestsLaunchTests.swift */,
); );
path = NotesUITests; path = NotesUITests;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C43417F228D4AD9C0098C15A /* Storage */ = { C4EEE46228DB3714003DDC24 /* Model */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C41A31FA28C4D8040019B951 /* PreferencesStorage.swift */, C4EEE47F28DB39F1003DDC24 /* Note+CoreDataClass.swift */,
C43417F328D4ADB10098C15A /* FileOperator.swift */, C4EEE48028DB39F1003DDC24 /* Note+CoreDataProperties.swift */,
C43417F528D4ADDB0098C15A /* FileStorage.swift */, );
C43417F928D4B9370098C15A /* Document.swift */, path = Model;
sourceTree = "<group>";
};
C4EEE46B28DB379B003DDC24 /* Storage */ = {
isa = PBXGroup;
children = (
C4EEE46528DB3790003DDC24 /* FileOperator.swift */,
C4EEE46628DB3790003DDC24 /* FileStorage.swift */,
C4EEE46428DB378F003DDC24 /* PreferencesStorage.swift */,
C4EEE48328DB3B6B003DDC24 /* CoreDataStorage.swift */,
); );
path = Storage; path = Storage;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C4EEE47428DB3938003DDC24 /* Frameworks */ = {
isa = PBXGroup;
children = (
C4EEE47528DB3938003DDC24 /* CoreData.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
C41A31C128C49B310019B951 /* Notes */ = { C4EEE41A28DB33D8003DDC24 /* Notes */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = C41A31EF28C49B320019B951 /* Build configuration list for PBXNativeTarget "Notes" */; buildConfigurationList = C4EEE44828DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "Notes" */;
buildPhases = ( buildPhases = (
C41A31BE28C49B310019B951 /* Sources */, C4EEE41728DB33D8003DDC24 /* Sources */,
C41A31BF28C49B310019B951 /* Frameworks */, C4EEE41828DB33D8003DDC24 /* Frameworks */,
C41A31C028C49B310019B951 /* Resources */, C4EEE41928DB33D8003DDC24 /* Resources */,
); );
buildRules = ( buildRules = (
); );
@ -175,107 +201,107 @@
); );
name = Notes; name = Notes;
productName = Notes; productName = Notes;
productReference = C41A31C228C49B310019B951 /* Notes.app */; productReference = C4EEE41B28DB33D8003DDC24 /* Notes.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
C41A31DA28C49B320019B951 /* NotesTests */ = { C4EEE43328DB33D9003DDC24 /* NotesTests */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = C41A31F228C49B320019B951 /* Build configuration list for PBXNativeTarget "NotesTests" */; buildConfigurationList = C4EEE44B28DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "NotesTests" */;
buildPhases = ( buildPhases = (
C41A31D728C49B320019B951 /* Sources */, C4EEE43028DB33D9003DDC24 /* Sources */,
C41A31D828C49B320019B951 /* Frameworks */, C4EEE43128DB33D9003DDC24 /* Frameworks */,
C41A31D928C49B320019B951 /* Resources */, C4EEE43228DB33D9003DDC24 /* Resources */,
); );
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
C41A31DD28C49B320019B951 /* PBXTargetDependency */, C4EEE43628DB33D9003DDC24 /* PBXTargetDependency */,
); );
name = NotesTests; name = NotesTests;
productName = NotesTests; productName = NotesTests;
productReference = C41A31DB28C49B320019B951 /* NotesTests.xctest */; productReference = C4EEE43428DB33D9003DDC24 /* NotesTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test"; productType = "com.apple.product-type.bundle.unit-test";
}; };
C41A31E428C49B320019B951 /* NotesUITests */ = { C4EEE43D28DB33D9003DDC24 /* NotesUITests */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = C41A31F528C49B320019B951 /* Build configuration list for PBXNativeTarget "NotesUITests" */; buildConfigurationList = C4EEE44E28DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "NotesUITests" */;
buildPhases = ( buildPhases = (
C41A31E128C49B320019B951 /* Sources */, C4EEE43A28DB33D9003DDC24 /* Sources */,
C41A31E228C49B320019B951 /* Frameworks */, C4EEE43B28DB33D9003DDC24 /* Frameworks */,
C41A31E328C49B320019B951 /* Resources */, C4EEE43C28DB33D9003DDC24 /* Resources */,
); );
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
C41A31E728C49B320019B951 /* PBXTargetDependency */, C4EEE44028DB33D9003DDC24 /* PBXTargetDependency */,
); );
name = NotesUITests; name = NotesUITests;
productName = NotesUITests; productName = NotesUITests;
productReference = C41A31E528C49B320019B951 /* NotesUITests.xctest */; productReference = C4EEE43E28DB33D9003DDC24 /* NotesUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing"; productType = "com.apple.product-type.bundle.ui-testing";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
/* Begin PBXProject section */ /* Begin PBXProject section */
C41A31BA28C49B310019B951 /* Project object */ = { C4EEE41328DB33D8003DDC24 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
BuildIndependentTargetsInParallel = 1; BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1340; LastSwiftUpdateCheck = 1400;
LastUpgradeCheck = 1340; LastUpgradeCheck = 1400;
TargetAttributes = { TargetAttributes = {
C41A31C128C49B310019B951 = { C4EEE41A28DB33D8003DDC24 = {
CreatedOnToolsVersion = 13.4.1; CreatedOnToolsVersion = 14.0;
}; };
C41A31DA28C49B320019B951 = { C4EEE43328DB33D9003DDC24 = {
CreatedOnToolsVersion = 13.4.1; CreatedOnToolsVersion = 14.0;
TestTargetID = C41A31C128C49B310019B951; TestTargetID = C4EEE41A28DB33D8003DDC24;
}; };
C41A31E428C49B320019B951 = { C4EEE43D28DB33D9003DDC24 = {
CreatedOnToolsVersion = 13.4.1; CreatedOnToolsVersion = 14.0;
TestTargetID = C41A31C128C49B310019B951; TestTargetID = C4EEE41A28DB33D8003DDC24;
}; };
}; };
}; };
buildConfigurationList = C41A31BD28C49B310019B951 /* Build configuration list for PBXProject "Notes" */; buildConfigurationList = C4EEE41628DB33D8003DDC24 /* Build configuration list for PBXProject "Notes" */;
compatibilityVersion = "Xcode 13.0"; compatibilityVersion = "Xcode 14.0";
developmentRegion = en; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
en, en,
Base, Base,
); );
mainGroup = C41A31B928C49B310019B951; mainGroup = C4EEE41228DB33D8003DDC24;
productRefGroup = C41A31C328C49B310019B951 /* Products */; productRefGroup = C4EEE41C28DB33D8003DDC24 /* Products */;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
C41A31C128C49B310019B951 /* Notes */, C4EEE41A28DB33D8003DDC24 /* Notes */,
C41A31DA28C49B320019B951 /* NotesTests */, C4EEE43328DB33D9003DDC24 /* NotesTests */,
C41A31E428C49B320019B951 /* NotesUITests */, C4EEE43D28DB33D9003DDC24 /* NotesUITests */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
C41A31C028C49B310019B951 /* Resources */ = { C4EEE41928DB33D8003DDC24 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
C41A31D528C49B320019B951 /* LaunchScreen.storyboard in Resources */, C4EEE42E28DB33D9003DDC24 /* LaunchScreen.storyboard in Resources */,
C41A31D228C49B320019B951 /* Assets.xcassets in Resources */, C4EEE42B28DB33D9003DDC24 /* Assets.xcassets in Resources */,
C41A31CD28C49B310019B951 /* Main.storyboard in Resources */, C4EEE42628DB33D8003DDC24 /* Main.storyboard in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
C41A31D928C49B320019B951 /* Resources */ = { C4EEE43228DB33D9003DDC24 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
C41A31E328C49B320019B951 /* Resources */ = { C4EEE43C28DB33D9003DDC24 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -285,68 +311,70 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
C41A31BE28C49B310019B951 /* Sources */ = { C4EEE41728DB33D8003DDC24 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
C41A31CA28C49B310019B951 /* ViewController.swift in Sources */, C4EEE48428DB3B6B003DDC24 /* CoreDataStorage.swift in Sources */,
C41A31C628C49B310019B951 /* AppDelegate.swift in Sources */, C4EEE48228DB39F1003DDC24 /* Note+CoreDataProperties.swift in Sources */,
C4EEE40728D89C46003DDC24 /* UIViewController+Extensions.swift in Sources */, C4EEE46A28DB3790003DDC24 /* PreferencesStorage.swift in Sources */,
C41A31FB28C4D8040019B951 /* PreferencesStorage.swift in Sources */, C4EEE42328DB33D8003DDC24 /* ViewController.swift in Sources */,
C41A31C828C49B310019B951 /* SceneDelegate.swift in Sources */, C4EEE46928DB3790003DDC24 /* FileStorage.swift in Sources */,
C43417F428D4ADB10098C15A /* FileOperator.swift in Sources */, C4EEE41F28DB33D8003DDC24 /* AppDelegate.swift in Sources */,
C43417FA28D4B9370098C15A /* Document.swift in Sources */, C4EEE42128DB33D8003DDC24 /* SceneDelegate.swift in Sources */,
C43417F628D4ADDB0098C15A /* FileStorage.swift in Sources */, C4EEE45328DB3423003DDC24 /* NoteViewController.swift in Sources */,
C41A31F928C49DC80019B951 /* NoteViewController.swift in Sources */, C4EEE46728DB3790003DDC24 /* FileOperator.swift in Sources */,
C41A31D028C49B310019B951 /* Notes.xcdatamodeld in Sources */, C4EEE48128DB39F1003DDC24 /* Note+CoreDataClass.swift in Sources */,
C4EEE45428DB3423003DDC24 /* UIViewController+Extensions.swift in Sources */,
C4EEE42928DB33D8003DDC24 /* Notes.xcdatamodeld in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
C41A31D728C49B320019B951 /* Sources */ = { C4EEE43028DB33D9003DDC24 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
C41A31E028C49B320019B951 /* NotesTests.swift in Sources */, C4EEE43928DB33D9003DDC24 /* NotesTests.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
C41A31E128C49B320019B951 /* Sources */ = { C4EEE43A28DB33D9003DDC24 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
C41A31EC28C49B320019B951 /* NotesUITestsLaunchTests.swift in Sources */, C4EEE44528DB33D9003DDC24 /* NotesUITestsLaunchTests.swift in Sources */,
C41A31EA28C49B320019B951 /* NotesUITests.swift in Sources */, C4EEE44328DB33D9003DDC24 /* NotesUITests.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */ /* Begin PBXTargetDependency section */
C41A31DD28C49B320019B951 /* PBXTargetDependency */ = { C4EEE43628DB33D9003DDC24 /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = C41A31C128C49B310019B951 /* Notes */; target = C4EEE41A28DB33D8003DDC24 /* Notes */;
targetProxy = C41A31DC28C49B320019B951 /* PBXContainerItemProxy */; targetProxy = C4EEE43528DB33D9003DDC24 /* PBXContainerItemProxy */;
}; };
C41A31E728C49B320019B951 /* PBXTargetDependency */ = { C4EEE44028DB33D9003DDC24 /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = C41A31C128C49B310019B951 /* Notes */; target = C4EEE41A28DB33D8003DDC24 /* Notes */;
targetProxy = C41A31E628C49B320019B951 /* PBXContainerItemProxy */; targetProxy = C4EEE43F28DB33D9003DDC24 /* PBXContainerItemProxy */;
}; };
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
C41A31CB28C49B310019B951 /* Main.storyboard */ = { C4EEE42428DB33D8003DDC24 /* Main.storyboard */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
C41A31CC28C49B310019B951 /* Base */, C4EEE42528DB33D8003DDC24 /* Base */,
); );
name = Main.storyboard; name = Main.storyboard;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C41A31D328C49B320019B951 /* LaunchScreen.storyboard */ = { C4EEE42C28DB33D9003DDC24 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
C41A31D428C49B320019B951 /* Base */, C4EEE42D28DB33D9003DDC24 /* Base */,
); );
name = LaunchScreen.storyboard; name = LaunchScreen.storyboard;
sourceTree = "<group>"; sourceTree = "<group>";
@ -354,13 +382,13 @@
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
C41A31ED28C49B320019B951 /* Debug */ = { C4EEE44628DB33D9003DDC24 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 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_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES; CLANG_ENABLE_OBJC_WEAK = YES;
@ -414,13 +442,13 @@
}; };
name = Debug; name = Debug;
}; };
C41A31EE28C49B320019B951 /* Release */ = { C4EEE44728DB33D9003DDC24 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 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_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES; CLANG_ENABLE_OBJC_WEAK = YES;
@ -468,12 +496,11 @@
}; };
name = Release; name = Release;
}; };
C41A31F028C49B320019B951 /* Debug */ = { C4EEE44928DB33D9003DDC24 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_ENTITLEMENTS = Notes/Notes.entitlements; CODE_SIGN_ENTITLEMENTS = Notes/Notes.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
@ -483,7 +510,6 @@
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -499,12 +525,11 @@
}; };
name = Debug; name = Debug;
}; };
C41A31F128C49B320019B951 /* Release */ = { C4EEE44A28DB33D9003DDC24 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_ENTITLEMENTS = Notes/Notes.entitlements; CODE_SIGN_ENTITLEMENTS = Notes/Notes.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
@ -514,7 +539,6 @@
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -530,7 +554,7 @@
}; };
name = Release; name = Release;
}; };
C41A31F328C49B320019B951 /* Debug */ = { C4EEE44C28DB33D9003DDC24 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
@ -539,18 +563,18 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 526E96RFNP; DEVELOPMENT_TEAM = 526E96RFNP;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.5; IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.NotesTests; PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.NotesTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; 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; name = Debug;
}; };
C41A31F428C49B320019B951 /* Release */ = { C4EEE44D28DB33D9003DDC24 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
@ -559,18 +583,18 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 526E96RFNP; DEVELOPMENT_TEAM = 526E96RFNP;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.5; IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.NotesTests; PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.NotesTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; 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; name = Release;
}; };
C41A31F628C49B320019B951 /* Debug */ = { C4EEE44F28DB33D9003DDC24 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
@ -588,7 +612,7 @@
}; };
name = Debug; name = Debug;
}; };
C41A31F728C49B320019B951 /* Release */ = { C4EEE45028DB33D9003DDC24 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
@ -609,38 +633,38 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
C41A31BD28C49B310019B951 /* Build configuration list for PBXProject "Notes" */ = { C4EEE41628DB33D8003DDC24 /* Build configuration list for PBXProject "Notes" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
C41A31ED28C49B320019B951 /* Debug */, C4EEE44628DB33D9003DDC24 /* Debug */,
C41A31EE28C49B320019B951 /* Release */, C4EEE44728DB33D9003DDC24 /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
C41A31EF28C49B320019B951 /* Build configuration list for PBXNativeTarget "Notes" */ = { C4EEE44828DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "Notes" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
C41A31F028C49B320019B951 /* Debug */, C4EEE44928DB33D9003DDC24 /* Debug */,
C41A31F128C49B320019B951 /* Release */, C4EEE44A28DB33D9003DDC24 /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
C41A31F228C49B320019B951 /* Build configuration list for PBXNativeTarget "NotesTests" */ = { C4EEE44B28DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "NotesTests" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
C41A31F328C49B320019B951 /* Debug */, C4EEE44C28DB33D9003DDC24 /* Debug */,
C41A31F428C49B320019B951 /* Release */, C4EEE44D28DB33D9003DDC24 /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
C41A31F528C49B320019B951 /* Build configuration list for PBXNativeTarget "NotesUITests" */ = { C4EEE44E28DB33D9003DDC24 /* Build configuration list for PBXNativeTarget "NotesUITests" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
C41A31F628C49B320019B951 /* Debug */, C4EEE44F28DB33D9003DDC24 /* Debug */,
C41A31F728C49B320019B951 /* Release */, C4EEE45028DB33D9003DDC24 /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
@ -648,17 +672,17 @@
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCVersionGroup section */ /* Begin XCVersionGroup section */
C41A31CE28C49B310019B951 /* Notes.xcdatamodeld */ = { C4EEE42728DB33D8003DDC24 /* Notes.xcdatamodeld */ = {
isa = XCVersionGroup; isa = XCVersionGroup;
children = ( children = (
C41A31CF28C49B310019B951 /* Notes.xcdatamodel */, C4EEE42828DB33D8003DDC24 /* Notes.xcdatamodel */,
); );
currentVersion = C41A31CF28C49B310019B951 /* Notes.xcdatamodel */; currentVersion = C4EEE42828DB33D8003DDC24 /* Notes.xcdatamodel */;
path = Notes.xcdatamodeld; path = Notes.xcdatamodeld;
sourceTree = "<group>"; sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel; versionGroupType = wrapper.xcdatamodel;
}; };
/* End XCVersionGroup section */ /* End XCVersionGroup section */
}; };
rootObject = C41A31BA28C49B310019B951 /* Project object */; rootObject = C4EEE41328DB33D8003DDC24 /* Project object */;
} }

@ -2,7 +2,7 @@
// AppDelegate.swift // AppDelegate.swift
// Notes // Notes
// //
// Created by Laurent Morvillier on 04/09/2022. // Created by Laurent Morvillier on 21/09/2022.
// //
import UIKit import UIKit
@ -11,23 +11,20 @@ import CoreData
@main @main
class AppDelegate: UIResponder, UIApplicationDelegate { class AppDelegate: UIResponder, UIApplicationDelegate {
static var shared: AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 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 { // Override point for customization after application launch.
// print("family: \(fontFamilyName)\n")
//
// for fontName in UIFont.fontNames(forFamilyName: fontFamilyName) {
// print("font: \(fontName)")
// }
// }
return true return true
} }
@ -75,8 +72,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}() }()
// MARK: - Core Data Saving support // MARK: - Core Data Saving support
static var viewContext: NSManagedObjectContext {
return self.shared.persistentContainer.viewContext
}
func saveContext () { func saveContext () {
print("save context...")
let context = persistentContainer.viewContext let context = persistentContainer.viewContext
if context.hasChanges { if context.hasChanges {
do { do {

@ -21,5 +21,9 @@
</array> </array>
</dict> </dict>
</dict> </dict>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
</dict> </dict>
</plist> </plist>

@ -0,0 +1,15 @@
//
// Note+CoreDataClass.swift
// Notes
//
// Created by Laurent Morvillier on 21/09/2022.
//
//
import Foundation
import CoreData
public class Note: NSManagedObject {
}

@ -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<Note> {
return NSFetchRequest<Note>(entityName: "Note")
}
@NSManaged public var content: String?
@NSManaged public var title: String?
@NSManaged public var lastEditDate: Date?
}
extension Note : Identifiable {
}

@ -10,7 +10,7 @@ import UIKit
class NoteViewController : UIViewController, UITextViewDelegate { class NoteViewController : UIViewController, UITextViewDelegate {
var filename: String = "main.txt" var note: Note? = nil
@IBOutlet weak var textView: UITextView! @IBOutlet weak var textView: UITextView!
@ -27,11 +27,7 @@ class NoteViewController : UIViewController, UITextViewDelegate {
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addHandler)) let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addHandler))
self.navigationItem.rightBarButtonItems = [addButton, shareButton] self.navigationItem.rightBarButtonItems = [addButton, shareButton]
do { self._loadLastNote()
self.textView.text = try FileStorage.main.getContent(filename: self.filename)
} catch {
self.showAlert(message: error.localizedDescription, title: "Error :(")
}
self.textView.font = UIFont.systemFont(ofSize: 18.0, weight: .regular) self.textView.font = UIFont.systemFont(ofSize: 18.0, weight: .regular)
self.textView.delegate = self self.textView.delegate = self
@ -39,6 +35,12 @@ class NoteViewController : UIViewController, UITextViewDelegate {
self._updateLastEdit() self._updateLastEdit()
/// Store notifications
NotificationCenter.default.addObserver(self, selector: #selector(self._storeRemoteChange(notification:)), name: .NSPersistentStoreCoordinatorStoresDidChange, object: nil)
/// Keyboard notifications
NotificationCenter.default.addObserver( NotificationCenter.default.addObserver(
self, self,
selector: #selector(keyboardDidShow(notification:)), 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) { 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() self._updateLastEdit()
} }
fileprivate func _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() let formattedDate: String = date.formatted()
self._lastEditLabel?.text = "last edit: \(formattedDate)" self._lastEditLabel?.text = "last edit: \(formattedDate)"
} }

@ -2,13 +2,15 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key> <key>com.apple.developer.icloud-container-identifiers</key>
<array/> <array>
<string>iCloud.com.staxriver.Note</string>
</array>
<key>com.apple.developer.icloud-services</key> <key>com.apple.developer.icloud-services</key>
<array> <array>
<string>CloudDocuments</string> <string>CloudKit</string>
</array> </array>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array/>
</dict> </dict>
</plist> </plist>

@ -1,4 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="true" userDefinedModelVersionIdentifier=""> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21279" systemVersion="21G83" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="YES" userDefinedModelVersionIdentifier="">
<elements/> <entity name="Note" representedClassName=".Note" syncable="YES">
<attribute name="content" optional="YES" attributeType="String"/>
<attribute name="lastEditDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="title" optional="YES" attributeType="String"/>
</entity>
</model> </model>

@ -2,7 +2,7 @@
// SceneDelegate.swift // SceneDelegate.swift
// Notes // Notes
// //
// Created by Laurent Morvillier on 04/09/2022. // Created by Laurent Morvillier on 21/09/2022.
// //
import UIKit import UIKit

@ -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()
}
}

@ -1,13 +0,0 @@
//
// Document.swift
// Notes
//
// Created by Laurent Morvillier on 16/09/2022.
//
import Foundation
import UIKit
class Document : UIDocument {
}

@ -15,6 +15,14 @@ struct StorageRequest {
let idleTimeBeforeSaving = 2.0 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? /// Should we have a way to go from local to iCloud?
/// https://stackoverflow.com/questions/33886846/best-way-to-use-icloud-documents-storage /// https://stackoverflow.com/questions/33886846/best-way-to-use-icloud-documents-storage
/// Should we store the files locally whatever the iCloud choice is? /// Should we store the files locally whatever the iCloud choice is?
@ -22,21 +30,32 @@ class FileStorage : FileOperator {
static var main: FileStorage = FileStorage() static var main: FileStorage = FileStorage()
fileprivate var _containerURL: URL? fileprivate var _cloudContainerURL: URL?
fileprivate var _cloudStorageDetermined: Bool = false fileprivate var _cloudStorageDetermined: Bool = false
fileprivate let containerTeamId = "notes"
fileprivate let containerIdentifier = "notes" fileprivate let containerIdentifier = "notes"
fileprivate var _timer: Timer? = nil fileprivate var _timer: Timer? = nil
fileprivate var _downloadTimer: Timer? = nil
fileprivate var _downloads: [NSMetadataItem] = []
fileprivate var _storageRequests: [String : String] = [:] fileprivate var _storageRequests: [String : String] = [:]
init() { init() {
let uit = FileManager.default.ubiquityIdentityToken
print("ubiquityIdentityToken = \(String(describing: uit))")
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
self._containerURL = FileManager.default.url(forUbiquityContainerIdentifier: self.containerIdentifier) self._cloudContainerURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)
self._cloudStorageDetermined = true 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 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 // MARK: - FileOperator
func requestStorage(filename: String, content: String) { func requestStorage(filename: String, content: String) {
@ -90,12 +190,18 @@ class FileStorage : FileOperator {
} }
fileprivate func _copyToCloudContainerIfNecessary(fileURL: URL, filename: String) throws { 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 return
} }
let cloudURL = containerURL.appending(path: filename) 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) try FileManager.default.copyItem(at: fileURL, to: cloudURL)
print("cloud copy to: \(cloudURL)")
} }
deinit { deinit {

@ -7,25 +7,25 @@
import Foundation import Foundation
//class PreferencesStorage : FileOperator { class PreferencesStorage : FileOperator {
//
// static var main = PreferencesStorage() static var main = PreferencesStorage()
//
// func requestStorage(filename: String, content: String) { func requestStorage(filename: String, content: String) {
// UserDefaults.standard.set(content, forKey: filename) UserDefaults.standard.set(content, forKey: filename)
// PreferencesStorage._fileChanged(filename: filename) PreferencesStorage._fileChanged(filename: filename)
// } }
//
// fileprivate static func _fileChanged(filename: String) { fileprivate static func _fileChanged(filename: String) {
// UserDefaults.standard.set(Date(), forKey: filename + "_date") UserDefaults.standard.set(Date(), forKey: filename + "_date")
// } }
//
// func getContent(filename: String) -> String? { func getContent(filename: String) -> String? {
// return UserDefaults.standard.object(forKey: filename) as? String return UserDefaults.standard.object(forKey: filename) as? String
// } }
//
// func lastEditDate(filename: String) -> Date? { func lastEditDate(filename: String) -> Date? {
// return UserDefaults.standard.object(forKey: filename + "_date") as? Date return UserDefaults.standard.object(forKey: filename + "_date") as? Date
// } }
//
//} }

@ -2,7 +2,7 @@
// ViewController.swift // ViewController.swift
// Notes // Notes
// //
// Created by Laurent Morvillier on 04/09/2022. // Created by Laurent Morvillier on 21/09/2022.
// //
import UIKit import UIKit

@ -2,13 +2,13 @@
// NotesTests.swift // NotesTests.swift
// NotesTests // NotesTests
// //
// Created by Laurent Morvillier on 04/09/2022. // Created by Laurent Morvillier on 21/09/2022.
// //
import XCTest import XCTest
@testable import Notes @testable import Notes
class NotesTests: XCTestCase { final class NotesTests: XCTestCase {
override func setUpWithError() throws { override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class. // Put setup code here. This method is called before the invocation of each test method in the class.

@ -2,12 +2,12 @@
// NotesUITests.swift // NotesUITests.swift
// NotesUITests // NotesUITests
// //
// Created by Laurent Morvillier on 04/09/2022. // Created by Laurent Morvillier on 21/09/2022.
// //
import XCTest import XCTest
class NotesUITests: XCTestCase { final class NotesUITests: XCTestCase {
override func setUpWithError() throws { override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class. // Put setup code here. This method is called before the invocation of each test method in the class.

@ -2,12 +2,12 @@
// NotesUITestsLaunchTests.swift // NotesUITestsLaunchTests.swift
// NotesUITests // NotesUITests
// //
// Created by Laurent Morvillier on 04/09/2022. // Created by Laurent Morvillier on 21/09/2022.
// //
import XCTest import XCTest
class NotesUITestsLaunchTests: XCTestCase { final class NotesUITestsLaunchTests: XCTestCase {
override class var runsForEachTargetApplicationUIConfiguration: Bool { override class var runsForEachTargetApplicationUIConfiguration: Bool {
true true

@ -1,3 +0,0 @@
# notes
application iOS de notes
Loading…
Cancel
Save