├── .DS_Store ├── Notes ├── .DS_Store ├── Assets.xcassets │ ├── .DS_Store │ ├── Contents.json │ ├── AccentColor.colorset │ │ ├── .DS_Store │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── Extensions │ └── Extensions.swift ├── View │ ├── ContentView.swift │ ├── ListCellView.swift │ ├── TextEditorView.swift │ ├── EditNotesView.swift │ └── NotesView.swift ├── NotesApp.swift ├── Model │ ├── NotesContainer.xcdatamodeld │ │ └── NotesContainer.xcdatamodel │ │ │ └── contents │ └── CoreDataManager.swift └── ViewModel │ └── NotesViewModel.swift ├── Images └── Notes-Poster.jpg ├── Notes.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── shashankbs.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── shashankbs.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bsshanky/Notes-SwiftUI/HEAD/.DS_Store -------------------------------------------------------------------------------- /Notes/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bsshanky/Notes-SwiftUI/HEAD/Notes/.DS_Store -------------------------------------------------------------------------------- /Images/Notes-Poster.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bsshanky/Notes-SwiftUI/HEAD/Images/Notes-Poster.jpg -------------------------------------------------------------------------------- /Notes/Assets.xcassets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bsshanky/Notes-SwiftUI/HEAD/Notes/Assets.xcassets/.DS_Store -------------------------------------------------------------------------------- /Notes/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Notes/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Notes/Assets.xcassets/AccentColor.colorset/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bsshanky/Notes-SwiftUI/HEAD/Notes/Assets.xcassets/AccentColor.colorset/.DS_Store -------------------------------------------------------------------------------- /Notes.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Notes.xcodeproj/xcuserdata/shashankbs.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Notes.xcodeproj/project.xcworkspace/xcuserdata/shashankbs.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bsshanky/Notes-SwiftUI/HEAD/Notes.xcodeproj/project.xcworkspace/xcuserdata/shashankbs.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Notes/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Notes.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Notes/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "universal", 6 | "reference" : "systemOrangeColor" 7 | }, 8 | "idiom" : "universal" 9 | } 10 | ], 11 | "info" : { 12 | "author" : "xcode", 13 | "version" : 1 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Notes/Extensions/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/27/24. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | // MARK: View 12 | 13 | extension View { 14 | func hideKeyboard() { 15 | UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Notes.xcodeproj/xcuserdata/shashankbs.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Notes.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Notes/View/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/27/24. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | @EnvironmentObject var notesViewModel: NotesViewModel 12 | 13 | var body: some View { 14 | 15 | Group { 16 | if notesViewModel.isDataLoaded { 17 | NotesView() 18 | } else { 19 | ProgressView("Loading...") 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Notes/View/ListCellView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ListCellView.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/27/24. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ListCellView: View { 11 | var note: NoteEntity 12 | 13 | var body: some View { 14 | VStack(alignment: .leading, spacing: 5) { 15 | Text(note.title ?? "New Note") 16 | .lineLimit(1) 17 | .font(.title3) 18 | .fontWeight(.bold) 19 | Text(note.content ?? "No context available") 20 | .lineLimit(1) 21 | .fontWeight(.light) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Notes/NotesApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotesApp.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/27/24. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct NotesToDocApp: App { 12 | let coreDataManager = CoreDataManager() 13 | @StateObject var notesViewModel: NotesViewModel 14 | 15 | init() { 16 | let viewModel = NotesViewModel(manager: coreDataManager) 17 | _notesViewModel = StateObject(wrappedValue: viewModel) 18 | } 19 | 20 | 21 | var body: some Scene { 22 | WindowGroup { 23 | ContentView() 24 | .environmentObject(notesViewModel) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Notes/Model/NotesContainer.xcdatamodeld/NotesContainer.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Notes/Model/CoreDataManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CoreDataManager.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/27/24. 6 | // 7 | 8 | import CoreData 9 | 10 | class CoreDataManager { 11 | 12 | let container: NSPersistentContainer 13 | 14 | init() { 15 | container = NSPersistentContainer(name: "NotesContainer") 16 | } 17 | 18 | func loadCoreData(completion: @escaping (Bool) -> Void) { 19 | container.loadPersistentStores { description, error in 20 | DispatchQueue.main.async { 21 | if let error = error { 22 | print("Core Data loading error: \(error.localizedDescription)") 23 | completion(false) 24 | } else { 25 | completion(true) 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Notes/View/TextEditorView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextEditorView.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/27/24. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TextEditorView: View { 11 | 12 | @Binding var string: String 13 | @State var textEditorHeight : CGFloat = 20 14 | 15 | var body: some View { 16 | 17 | ZStack(alignment: .leading) { 18 | 19 | Text(string) 20 | .foregroundColor(.clear) 21 | .padding(10) 22 | .background(GeometryReader { 23 | Color.clear.preference(key: ViewHeightKey.self, 24 | value: $0.frame(in: .local).size.height) 25 | }) 26 | 27 | TextEditor(text: $string) 28 | .frame(height: max(20,textEditorHeight)) 29 | .border(.clear) 30 | 31 | if string.isEmpty { 32 | 33 | Text("Content") 34 | .font(.title3) 35 | .foregroundColor(.gray) 36 | .disabled(true) 37 | .opacity(0.6) 38 | .padding([.top, .leading], 4) 39 | } 40 | 41 | }.onPreferenceChange(ViewHeightKey.self) { textEditorHeight = $0 } 42 | } 43 | } 44 | 45 | struct ViewHeightKey: PreferenceKey { 46 | static var defaultValue: CGFloat { 0 } 47 | static func reduce(value: inout Value, nextValue: () -> Value) { 48 | value = value + nextValue() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Notes/ViewModel/NotesViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotesViewModel.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/28/24. 6 | // 7 | 8 | import Foundation 9 | import CoreData 10 | 11 | class NotesViewModel: ObservableObject { 12 | 13 | let manager: CoreDataManager 14 | @Published var notes: [NoteEntity] = [] 15 | @Published var isDataLoaded = false 16 | 17 | init(manager: CoreDataManager) { 18 | self.manager = manager 19 | loadData() 20 | } 21 | 22 | func loadData() { 23 | manager.loadCoreData { [weak self] success in 24 | DispatchQueue.main.async { 25 | self?.isDataLoaded = success 26 | if success { 27 | self?.fetchNotes() 28 | } 29 | } 30 | } 31 | } 32 | 33 | func fetchNotes(with searchText: String = "") { 34 | let request: NSFetchRequest = NoteEntity.fetchRequest() 35 | request.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: false)] 36 | 37 | if !searchText.isEmpty { 38 | request.predicate = NSPredicate(format: "title CONTAINS %@", searchText) 39 | } 40 | 41 | do { 42 | notes = try manager.container.viewContext.fetch(request) 43 | } catch { 44 | print("Error fetching notes: \(error)") 45 | } 46 | } 47 | 48 | func createNote() -> NoteEntity { 49 | let newNote = NoteEntity(context: manager.container.viewContext) 50 | newNote.id = UUID() 51 | newNote.timestamp = Date() 52 | saveContext() 53 | fetchNotes() // Refresh notes list 54 | 55 | return newNote 56 | } 57 | 58 | func deleteNote(_ note: NoteEntity) { 59 | manager.container.viewContext.delete(note) 60 | saveContext() 61 | fetchNotes() // Refresh notes list 62 | } 63 | 64 | func updateNote(_ note: NoteEntity, title: String, content: String) { 65 | note.title = title 66 | note.content = content 67 | saveContext() 68 | fetchNotes() // Refresh notes list 69 | } 70 | 71 | func searchNotes(with searchText: String) { 72 | fetchNotes(with: searchText) 73 | } 74 | 75 | private func saveContext() { 76 | do { 77 | try manager.container.viewContext.save() 78 | } catch { 79 | print("Error saving context: \(error)") 80 | } 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Notes SwiftUI 2 | 3 | ![Getting Started](./Images/Notes-Poster.jpg) 4 | 5 | ## Motivation 6 | 7 | The primary motivation behind developing the NotesToDoc app was to replicate the user interface of the native iOS Notes application. This project was embarked upon as a means to delve deeper into the intricacies of UI development and to understand the underlying mechanics of how such an application operates. By recreating the Notes app, the project aims to offer profound insights into the design and functionality aspects, thereby sharpening the skills needed to craft intuitive and user-friendly applications. 8 | 9 | ## Features 10 | 11 | The Notes app comes equipped with a suite of features designed to enhance the user experience and provide a seamless note-taking process. The core features of the application include: 12 | 13 | 1. Universal Compatibility: The app is designed to support both iPad and iPhone screens, ensuring a consistent and responsive user experience across all devices. 14 | 15 | 2. Mode Versatility: With support for Light and Dark modes, the app offers flexibility in appearance, allowing users to choose the theme that best suits their preference or ambient lighting conditions. 16 | 17 | 3. Persistent Data Storage: Utilizing Core Data, the app ensures that all notes are stored persistently. This means users can exit the app and return to find their notes exactly as they left them, ensuring data longevity and reliability. 18 | 19 | 4. Familiar User Interface: The UI of the NotesToDoc app closely mimics that of the native iOS notes app. This design choice provides users with a familiar environment, minimizing the learning curve and enhancing the overall user experience. 20 | 21 | ## Future Scope 22 | 23 | While the Notes app already offers a robust note-taking solution, there are plans to further enhance its capabilities and integrate additional features. The future developments for the app include: 24 | 25 | 1. Integration of 'Sign in with Apple': To provide a more personalized and secure experience, there are plans to integrate 'Sign in with Apple'. This feature will not only enhance security but also pave the way for more personalized features in the future. 26 | 27 | 2. CloudKit Synchronization: In order to offer a seamless experience across different devices, the app aims to integrate CloudKit. This will allow users to synchronize their notes between different devices that are logged in with the same Apple ID, ensuring that their notes are always accessible, regardless of the device in use. 28 | 29 | -------------------------------------------------------------------------------- /Notes/View/EditNotesView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EditNotesView.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/27/24. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct EditNotesView: View { 11 | 12 | @EnvironmentObject var vm: NotesViewModel 13 | 14 | @State var note: NoteEntity? 15 | @State private var title: String = "" 16 | @State private var content: String = "" 17 | 18 | @FocusState private var contentEditorInFocus: Bool 19 | 20 | var body: some View { 21 | 22 | ScrollView { 23 | VStack(alignment: .leading, spacing: 20) { 24 | 25 | TextField("Title", text: $title, axis: .vertical) 26 | .font(.title.bold()) 27 | .submitLabel(.next) 28 | .onChange(of: title, { 29 | guard let newValueLastChar = title.last else { return } 30 | if newValueLastChar == "\n" { 31 | title.removeLast() 32 | contentEditorInFocus = true 33 | } 34 | }) 35 | 36 | TextEditorView(string: $content) 37 | .scrollDisabled(true) 38 | .font(.title3) 39 | .focused($contentEditorInFocus) 40 | 41 | 42 | } 43 | .padding(10) 44 | } 45 | .navigationBarTitleDisplayMode(.inline) 46 | .toolbar { 47 | ToolbarItem(placement: .keyboard) { 48 | HStack { 49 | Spacer() 50 | Button("Done") { 51 | self.hideKeyboard() 52 | // Save to Core Data 53 | self.updateNote(title: title, content: content) 54 | } 55 | } 56 | } 57 | } 58 | .onAppear { 59 | 60 | if let note = note { 61 | self.title = note.title ?? "" 62 | self.content = note.content ?? "" 63 | } 64 | } 65 | 66 | } 67 | 68 | // MARK: Core Data Operations 69 | 70 | func updateNote(title: String, content: String) { 71 | 72 | if (title.isEmpty) && (content.isEmpty) { 73 | return 74 | } 75 | 76 | guard let note = note else { return } 77 | 78 | vm.updateNote(note, title: title, content: content) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Notes/View/NotesView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUIView.swift 3 | // Notes 4 | // 5 | // Created by Shashank on 1/27/24. 6 | // 7 | 8 | import SwiftUI 9 | import CoreData 10 | 11 | struct NotesView: View { 12 | 13 | @EnvironmentObject var vm: NotesViewModel 14 | @State var showConfirmationDialogue: Bool = false 15 | @State var showOverlay: Bool = false 16 | @State private var searchText = "" 17 | 18 | @State private var selectedNote: NoteEntity? 19 | 20 | var groupedByDate: [Date: [NoteEntity]] { 21 | let calendar = Calendar.current 22 | return Dictionary(grouping: vm.notes) { noteEntity in 23 | let dateComponents = calendar.dateComponents([.year, .month, .day], from: noteEntity.timestamp!) 24 | return calendar.date(from: dateComponents) ?? Date() 25 | } 26 | } 27 | 28 | var headers: [Date] { 29 | groupedByDate.map { $0.key }.sorted(by: { $0 > $1 }) 30 | } 31 | 32 | var body: some View { 33 | 34 | NavigationSplitView { 35 | // sidebar 36 | List(selection: $selectedNote) { 37 | ForEach(headers, id: \.self) { header in 38 | Section(header: Text(header, style: .date)) { 39 | ForEach(groupedByDate[header]!) { note in 40 | NavigationLink(value: note) { 41 | ListCellView(note: note) 42 | 43 | } 44 | } 45 | 46 | .onDelete(perform: { indexSet in 47 | deleteNote(in: header, at: indexSet) 48 | }) 49 | } 50 | } 51 | } 52 | .id(UUID()) 53 | .navigationTitle("Notes") 54 | .searchable(text: $searchText) 55 | .onChange(of: searchText) { 56 | // MARK: Core Data Operations 57 | vm.searchNotes(with: searchText) 58 | } 59 | .toolbar { 60 | ToolbarItem(placement: .navigationBarTrailing) { 61 | 62 | Button { 63 | // Create a new empty note here: 64 | createNewNote() 65 | 66 | } label: { 67 | Image(systemName: "note.text.badge.plus") 68 | .foregroundColor(Color(UIColor.systemOrange)) 69 | } 70 | } 71 | } 72 | 73 | } detail: { 74 | // item details 75 | if let selectedNote { 76 | EditNotesView(note: selectedNote) 77 | .id(selectedNote) 78 | } else { 79 | Text("Select a Note.") 80 | } 81 | 82 | } 83 | } 84 | 85 | // MARK: Core Data Operations 86 | 87 | private func createNewNote() { 88 | selectedNote = nil 89 | selectedNote = vm.createNote() 90 | } 91 | 92 | private func deleteNote(in header: Date, at offsets: IndexSet) { 93 | offsets.forEach { index in 94 | if let noteToDelete = groupedByDate[header]?[index] { 95 | 96 | if noteToDelete == selectedNote { 97 | selectedNote = nil 98 | } 99 | 100 | vm.deleteNote(noteToDelete) 101 | } 102 | } 103 | } 104 | } 105 | 106 | #Preview { 107 | NotesView() 108 | } 109 | 110 | -------------------------------------------------------------------------------- /Notes.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DB7654D62B66C39D008CCE12 /* NotesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7654D52B66C39D008CCE12 /* NotesViewModel.swift */; }; 11 | DB9C1E702B65BE9200964A11 /* NotesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E6F2B65BE9200964A11 /* NotesApp.swift */; }; 12 | DB9C1E722B65BE9200964A11 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E712B65BE9200964A11 /* ContentView.swift */; }; 13 | DB9C1E742B65BE9300964A11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB9C1E732B65BE9300964A11 /* Assets.xcassets */; }; 14 | DB9C1E772B65BE9300964A11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB9C1E762B65BE9300964A11 /* Preview Assets.xcassets */; }; 15 | DB9C1E7E2B65BEDB00964A11 /* NotesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E7D2B65BEDB00964A11 /* NotesView.swift */; }; 16 | DB9C1E802B65BF1300964A11 /* EditNotesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E7F2B65BF1300964A11 /* EditNotesView.swift */; }; 17 | DB9C1E822B65BF2F00964A11 /* ListCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E812B65BF2F00964A11 /* ListCellView.swift */; }; 18 | DB9C1E842B65BF4F00964A11 /* TextEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E832B65BF4F00964A11 /* TextEditorView.swift */; }; 19 | DB9C1E862B65BF6D00964A11 /* CoreDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E852B65BF6D00964A11 /* CoreDataManager.swift */; }; 20 | DB9C1E882B65C18B00964A11 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E872B65C18B00964A11 /* Extensions.swift */; }; 21 | DB9C1E912B65C43600964A11 /* NotesContainer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DB9C1E8F2B65C43600964A11 /* NotesContainer.xcdatamodeld */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | DB7654D52B66C39D008CCE12 /* NotesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesViewModel.swift; sourceTree = ""; }; 26 | DB9C1E6C2B65BE9200964A11 /* Notes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Notes.app; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | DB9C1E6F2B65BE9200964A11 /* NotesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesApp.swift; sourceTree = ""; }; 28 | DB9C1E712B65BE9200964A11 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 29 | DB9C1E732B65BE9300964A11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 30 | DB9C1E762B65BE9300964A11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 31 | DB9C1E7D2B65BEDB00964A11 /* NotesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesView.swift; sourceTree = ""; }; 32 | DB9C1E7F2B65BF1300964A11 /* EditNotesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditNotesView.swift; sourceTree = ""; }; 33 | DB9C1E812B65BF2F00964A11 /* ListCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCellView.swift; sourceTree = ""; }; 34 | DB9C1E832B65BF4F00964A11 /* TextEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEditorView.swift; sourceTree = ""; }; 35 | DB9C1E852B65BF6D00964A11 /* CoreDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataManager.swift; sourceTree = ""; }; 36 | DB9C1E872B65C18B00964A11 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 37 | DB9C1E902B65C43600964A11 /* NotesContainer.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = NotesContainer.xcdatamodel; sourceTree = ""; }; 38 | /* End PBXFileReference section */ 39 | 40 | /* Begin PBXFrameworksBuildPhase section */ 41 | DB9C1E692B65BE9200964A11 /* Frameworks */ = { 42 | isa = PBXFrameworksBuildPhase; 43 | buildActionMask = 2147483647; 44 | files = ( 45 | ); 46 | runOnlyForDeploymentPostprocessing = 0; 47 | }; 48 | /* End PBXFrameworksBuildPhase section */ 49 | 50 | /* Begin PBXGroup section */ 51 | DB84073D2B6762A10012A6D7 /* View */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | DB9C1E712B65BE9200964A11 /* ContentView.swift */, 55 | DB9C1E7D2B65BEDB00964A11 /* NotesView.swift */, 56 | DB9C1E7F2B65BF1300964A11 /* EditNotesView.swift */, 57 | DB9C1E812B65BF2F00964A11 /* ListCellView.swift */, 58 | DB9C1E832B65BF4F00964A11 /* TextEditorView.swift */, 59 | ); 60 | path = View; 61 | sourceTree = ""; 62 | }; 63 | DB84073E2B6762BA0012A6D7 /* ViewModel */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | DB7654D52B66C39D008CCE12 /* NotesViewModel.swift */, 67 | ); 68 | path = ViewModel; 69 | sourceTree = ""; 70 | }; 71 | DB84073F2B6762DC0012A6D7 /* Model */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | DB9C1E8F2B65C43600964A11 /* NotesContainer.xcdatamodeld */, 75 | DB9C1E852B65BF6D00964A11 /* CoreDataManager.swift */, 76 | ); 77 | path = Model; 78 | sourceTree = ""; 79 | }; 80 | DB8407402B6762F90012A6D7 /* Extensions */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | DB9C1E872B65C18B00964A11 /* Extensions.swift */, 84 | ); 85 | path = Extensions; 86 | sourceTree = ""; 87 | }; 88 | DB9C1E632B65BE9200964A11 = { 89 | isa = PBXGroup; 90 | children = ( 91 | DB9C1E6E2B65BE9200964A11 /* Notes */, 92 | DB9C1E6D2B65BE9200964A11 /* Products */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | DB9C1E6D2B65BE9200964A11 /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | DB9C1E6C2B65BE9200964A11 /* Notes.app */, 100 | ); 101 | name = Products; 102 | sourceTree = ""; 103 | }; 104 | DB9C1E6E2B65BE9200964A11 /* Notes */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | DB9C1E6F2B65BE9200964A11 /* NotesApp.swift */, 108 | DB9C1E732B65BE9300964A11 /* Assets.xcassets */, 109 | DB9C1E752B65BE9300964A11 /* Preview Content */, 110 | DB84073D2B6762A10012A6D7 /* View */, 111 | DB84073F2B6762DC0012A6D7 /* Model */, 112 | DB8407402B6762F90012A6D7 /* Extensions */, 113 | DB84073E2B6762BA0012A6D7 /* ViewModel */, 114 | ); 115 | path = Notes; 116 | sourceTree = ""; 117 | }; 118 | DB9C1E752B65BE9300964A11 /* Preview Content */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | DB9C1E762B65BE9300964A11 /* Preview Assets.xcassets */, 122 | ); 123 | path = "Preview Content"; 124 | sourceTree = ""; 125 | }; 126 | /* End PBXGroup section */ 127 | 128 | /* Begin PBXNativeTarget section */ 129 | DB9C1E6B2B65BE9200964A11 /* Notes */ = { 130 | isa = PBXNativeTarget; 131 | buildConfigurationList = DB9C1E7A2B65BE9300964A11 /* Build configuration list for PBXNativeTarget "Notes" */; 132 | buildPhases = ( 133 | DB9C1E682B65BE9200964A11 /* Sources */, 134 | DB9C1E692B65BE9200964A11 /* Frameworks */, 135 | DB9C1E6A2B65BE9200964A11 /* Resources */, 136 | ); 137 | buildRules = ( 138 | ); 139 | dependencies = ( 140 | ); 141 | name = Notes; 142 | productName = Notes; 143 | productReference = DB9C1E6C2B65BE9200964A11 /* Notes.app */; 144 | productType = "com.apple.product-type.application"; 145 | }; 146 | /* End PBXNativeTarget section */ 147 | 148 | /* Begin PBXProject section */ 149 | DB9C1E642B65BE9200964A11 /* Project object */ = { 150 | isa = PBXProject; 151 | attributes = { 152 | BuildIndependentTargetsInParallel = 1; 153 | LastSwiftUpdateCheck = 1520; 154 | LastUpgradeCheck = 1520; 155 | TargetAttributes = { 156 | DB9C1E6B2B65BE9200964A11 = { 157 | CreatedOnToolsVersion = 15.2; 158 | }; 159 | }; 160 | }; 161 | buildConfigurationList = DB9C1E672B65BE9200964A11 /* Build configuration list for PBXProject "Notes" */; 162 | compatibilityVersion = "Xcode 14.0"; 163 | developmentRegion = en; 164 | hasScannedForEncodings = 0; 165 | knownRegions = ( 166 | en, 167 | Base, 168 | ); 169 | mainGroup = DB9C1E632B65BE9200964A11; 170 | productRefGroup = DB9C1E6D2B65BE9200964A11 /* Products */; 171 | projectDirPath = ""; 172 | projectRoot = ""; 173 | targets = ( 174 | DB9C1E6B2B65BE9200964A11 /* Notes */, 175 | ); 176 | }; 177 | /* End PBXProject section */ 178 | 179 | /* Begin PBXResourcesBuildPhase section */ 180 | DB9C1E6A2B65BE9200964A11 /* Resources */ = { 181 | isa = PBXResourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | DB9C1E772B65BE9300964A11 /* Preview Assets.xcassets in Resources */, 185 | DB9C1E742B65BE9300964A11 /* Assets.xcassets in Resources */, 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXResourcesBuildPhase section */ 190 | 191 | /* Begin PBXSourcesBuildPhase section */ 192 | DB9C1E682B65BE9200964A11 /* Sources */ = { 193 | isa = PBXSourcesBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | DB9C1E842B65BF4F00964A11 /* TextEditorView.swift in Sources */, 197 | DB9C1E802B65BF1300964A11 /* EditNotesView.swift in Sources */, 198 | DB9C1E722B65BE9200964A11 /* ContentView.swift in Sources */, 199 | DB9C1E882B65C18B00964A11 /* Extensions.swift in Sources */, 200 | DB9C1E702B65BE9200964A11 /* NotesApp.swift in Sources */, 201 | DB9C1E7E2B65BEDB00964A11 /* NotesView.swift in Sources */, 202 | DB7654D62B66C39D008CCE12 /* NotesViewModel.swift in Sources */, 203 | DB9C1E912B65C43600964A11 /* NotesContainer.xcdatamodeld in Sources */, 204 | DB9C1E862B65BF6D00964A11 /* CoreDataManager.swift in Sources */, 205 | DB9C1E822B65BF2F00964A11 /* ListCellView.swift in Sources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXSourcesBuildPhase section */ 210 | 211 | /* Begin XCBuildConfiguration section */ 212 | DB9C1E782B65BE9300964A11 /* Debug */ = { 213 | isa = XCBuildConfiguration; 214 | buildSettings = { 215 | ALWAYS_SEARCH_USER_PATHS = NO; 216 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 217 | CLANG_ANALYZER_NONNULL = YES; 218 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 219 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 220 | CLANG_ENABLE_MODULES = YES; 221 | CLANG_ENABLE_OBJC_ARC = YES; 222 | CLANG_ENABLE_OBJC_WEAK = YES; 223 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 224 | CLANG_WARN_BOOL_CONVERSION = YES; 225 | CLANG_WARN_COMMA = YES; 226 | CLANG_WARN_CONSTANT_CONVERSION = YES; 227 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 228 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 229 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 230 | CLANG_WARN_EMPTY_BODY = YES; 231 | CLANG_WARN_ENUM_CONVERSION = YES; 232 | CLANG_WARN_INFINITE_RECURSION = YES; 233 | CLANG_WARN_INT_CONVERSION = YES; 234 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 235 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 236 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 237 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 238 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 239 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 240 | CLANG_WARN_STRICT_PROTOTYPES = YES; 241 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 242 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 243 | CLANG_WARN_UNREACHABLE_CODE = YES; 244 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 245 | COPY_PHASE_STRIP = NO; 246 | DEBUG_INFORMATION_FORMAT = dwarf; 247 | ENABLE_STRICT_OBJC_MSGSEND = YES; 248 | ENABLE_TESTABILITY = YES; 249 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 250 | GCC_C_LANGUAGE_STANDARD = gnu17; 251 | GCC_DYNAMIC_NO_PIC = NO; 252 | GCC_NO_COMMON_BLOCKS = YES; 253 | GCC_OPTIMIZATION_LEVEL = 0; 254 | GCC_PREPROCESSOR_DEFINITIONS = ( 255 | "DEBUG=1", 256 | "$(inherited)", 257 | ); 258 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 259 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 260 | GCC_WARN_UNDECLARED_SELECTOR = YES; 261 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 262 | GCC_WARN_UNUSED_FUNCTION = YES; 263 | GCC_WARN_UNUSED_VARIABLE = YES; 264 | IPHONEOS_DEPLOYMENT_TARGET = 17.2; 265 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 266 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 267 | MTL_FAST_MATH = YES; 268 | ONLY_ACTIVE_ARCH = YES; 269 | SDKROOT = iphoneos; 270 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 271 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 272 | }; 273 | name = Debug; 274 | }; 275 | DB9C1E792B65BE9300964A11 /* Release */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | ALWAYS_SEARCH_USER_PATHS = NO; 279 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 280 | CLANG_ANALYZER_NONNULL = YES; 281 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 282 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 283 | CLANG_ENABLE_MODULES = YES; 284 | CLANG_ENABLE_OBJC_ARC = YES; 285 | CLANG_ENABLE_OBJC_WEAK = YES; 286 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 287 | CLANG_WARN_BOOL_CONVERSION = YES; 288 | CLANG_WARN_COMMA = YES; 289 | CLANG_WARN_CONSTANT_CONVERSION = YES; 290 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 291 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 292 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 293 | CLANG_WARN_EMPTY_BODY = YES; 294 | CLANG_WARN_ENUM_CONVERSION = YES; 295 | CLANG_WARN_INFINITE_RECURSION = YES; 296 | CLANG_WARN_INT_CONVERSION = YES; 297 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 298 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 299 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 300 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 301 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 302 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 303 | CLANG_WARN_STRICT_PROTOTYPES = YES; 304 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 305 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 306 | CLANG_WARN_UNREACHABLE_CODE = YES; 307 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 308 | COPY_PHASE_STRIP = NO; 309 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 310 | ENABLE_NS_ASSERTIONS = NO; 311 | ENABLE_STRICT_OBJC_MSGSEND = YES; 312 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 313 | GCC_C_LANGUAGE_STANDARD = gnu17; 314 | GCC_NO_COMMON_BLOCKS = YES; 315 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 316 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 317 | GCC_WARN_UNDECLARED_SELECTOR = YES; 318 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 319 | GCC_WARN_UNUSED_FUNCTION = YES; 320 | GCC_WARN_UNUSED_VARIABLE = YES; 321 | IPHONEOS_DEPLOYMENT_TARGET = 17.2; 322 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 323 | MTL_ENABLE_DEBUG_INFO = NO; 324 | MTL_FAST_MATH = YES; 325 | SDKROOT = iphoneos; 326 | SWIFT_COMPILATION_MODE = wholemodule; 327 | VALIDATE_PRODUCT = YES; 328 | }; 329 | name = Release; 330 | }; 331 | DB9C1E7B2B65BE9300964A11 /* Debug */ = { 332 | isa = XCBuildConfiguration; 333 | buildSettings = { 334 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 335 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 336 | CODE_SIGN_IDENTITY = "Apple Development"; 337 | CODE_SIGN_STYLE = Automatic; 338 | CURRENT_PROJECT_VERSION = 1; 339 | DEVELOPMENT_ASSET_PATHS = "\"Notes/Preview Content\""; 340 | DEVELOPMENT_TEAM = F4T4372M48; 341 | ENABLE_PREVIEWS = YES; 342 | GENERATE_INFOPLIST_FILE = YES; 343 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 344 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 345 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 346 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 347 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 348 | LD_RUNPATH_SEARCH_PATHS = ( 349 | "$(inherited)", 350 | "@executable_path/Frameworks", 351 | ); 352 | MARKETING_VERSION = 1.0; 353 | PRODUCT_BUNDLE_IDENTIFIER = com.shashank.Notes; 354 | PRODUCT_NAME = "$(TARGET_NAME)"; 355 | PROVISIONING_PROFILE_SPECIFIER = ""; 356 | SWIFT_EMIT_LOC_STRINGS = YES; 357 | SWIFT_VERSION = 5.0; 358 | TARGETED_DEVICE_FAMILY = "1,2"; 359 | }; 360 | name = Debug; 361 | }; 362 | DB9C1E7C2B65BE9300964A11 /* Release */ = { 363 | isa = XCBuildConfiguration; 364 | buildSettings = { 365 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 366 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 367 | CODE_SIGN_IDENTITY = "Apple Development"; 368 | CODE_SIGN_STYLE = Automatic; 369 | CURRENT_PROJECT_VERSION = 1; 370 | DEVELOPMENT_ASSET_PATHS = "\"Notes/Preview Content\""; 371 | DEVELOPMENT_TEAM = F4T4372M48; 372 | ENABLE_PREVIEWS = YES; 373 | GENERATE_INFOPLIST_FILE = YES; 374 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 375 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 376 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 377 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 378 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 379 | LD_RUNPATH_SEARCH_PATHS = ( 380 | "$(inherited)", 381 | "@executable_path/Frameworks", 382 | ); 383 | MARKETING_VERSION = 1.0; 384 | PRODUCT_BUNDLE_IDENTIFIER = com.shashank.Notes; 385 | PRODUCT_NAME = "$(TARGET_NAME)"; 386 | PROVISIONING_PROFILE_SPECIFIER = ""; 387 | SWIFT_EMIT_LOC_STRINGS = YES; 388 | SWIFT_VERSION = 5.0; 389 | TARGETED_DEVICE_FAMILY = "1,2"; 390 | }; 391 | name = Release; 392 | }; 393 | /* End XCBuildConfiguration section */ 394 | 395 | /* Begin XCConfigurationList section */ 396 | DB9C1E672B65BE9200964A11 /* Build configuration list for PBXProject "Notes" */ = { 397 | isa = XCConfigurationList; 398 | buildConfigurations = ( 399 | DB9C1E782B65BE9300964A11 /* Debug */, 400 | DB9C1E792B65BE9300964A11 /* Release */, 401 | ); 402 | defaultConfigurationIsVisible = 0; 403 | defaultConfigurationName = Release; 404 | }; 405 | DB9C1E7A2B65BE9300964A11 /* Build configuration list for PBXNativeTarget "Notes" */ = { 406 | isa = XCConfigurationList; 407 | buildConfigurations = ( 408 | DB9C1E7B2B65BE9300964A11 /* Debug */, 409 | DB9C1E7C2B65BE9300964A11 /* Release */, 410 | ); 411 | defaultConfigurationIsVisible = 0; 412 | defaultConfigurationName = Release; 413 | }; 414 | /* End XCConfigurationList section */ 415 | 416 | /* Begin XCVersionGroup section */ 417 | DB9C1E8F2B65C43600964A11 /* NotesContainer.xcdatamodeld */ = { 418 | isa = XCVersionGroup; 419 | children = ( 420 | DB9C1E902B65C43600964A11 /* NotesContainer.xcdatamodel */, 421 | ); 422 | currentVersion = DB9C1E902B65C43600964A11 /* NotesContainer.xcdatamodel */; 423 | path = NotesContainer.xcdatamodeld; 424 | sourceTree = ""; 425 | versionGroupType = wrapper.xcdatamodel; 426 | }; 427 | /* End XCVersionGroup section */ 428 | }; 429 | rootObject = DB9C1E642B65BE9200964A11 /* Project object */; 430 | } 431 | --------------------------------------------------------------------------------