diff --git a/Shared/Resources/Licenses/Sparkle-License.txt b/Shared/Resources/Licenses/Sparkle-License.txt
new file mode 100644
index 0000000..1e9b1c6
--- /dev/null
+++ b/Shared/Resources/Licenses/Sparkle-License.txt
@@ -0,0 +1,61 @@
+Copyright (c) 2006-2013 Andy Matuschak.
+Copyright (c) 2009-2013 Elgato Systems GmbH.
+Copyright (c) 2011-2014 Kornel Lesiński.
+Copyright (c) 2015-2017 Mayur Pawashe.
+Copyright (c) 2014 C.W. Betts.
+Copyright (c) 2014 Petroules Corporation.
+Copyright (c) 2014 Big Nerd Ranch.
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+=================
+EXTERNAL LICENSES
+=================
+
+bspatch.c and bsdiff.c, from bsdiff 4.3 :
+    Copyright (c) 2003-2005 Colin Percival.
+
+sais.c and sais.c, from sais-lite (2010/08/07) :
+    Copyright (c) 2008-2010 Yuta Mori.
+
+SUDSAVerifier.m:
+    Copyright (c) 2011 Mark Hamlin.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted providing that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/Shared/WriteFreely_MultiPlatformApp.swift b/Shared/WriteFreely_MultiPlatformApp.swift
index be464cb..61a634a 100644
--- a/Shared/WriteFreely_MultiPlatformApp.swift
+++ b/Shared/WriteFreely_MultiPlatformApp.swift
@@ -1,122 +1,141 @@
 import SwiftUI
 
+#if os(macOS)
+import Sparkle
+#endif
+
 @main
 struct CheckForDebugModifier {
     static func main() {
         #if os(macOS)
             if NSEvent.modifierFlags.contains(.shift) {
                 print("Debug launch detected")
                 // Run debug-mode launch code here
             } else {
                 print("Normal launch detected")
                 // Don't do anything
             }
         #endif
         WriteFreely_MultiPlatformApp.main()
     }
 }
 
 struct WriteFreely_MultiPlatformApp: App {
     @StateObject private var model = WriteFreelyModel()
 
     #if os(macOS)
+    // swiftlint:disable:next weak_delegate
+    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
     @State private var selectedTab = 0
     #endif
 
     var body: some Scene {
         WindowGroup {
             ContentView()
                 .onAppear(perform: {
                     if let lastDraft = model.editor.fetchLastDraftFromUserDefaults() {
                         self.model.selectedPost = lastDraft
                     } else {
                         createNewLocalPost()
                     }
                 })
                 .environmentObject(model)
                 .environment(\.managedObjectContext, LocalStorageManager.persistentContainer.viewContext)
 //                .preferredColorScheme(preferences.selectedColorScheme)    // See PreferencesModel for info.
         }
         .commands {
+            #if os(macOS)
+            CommandGroup(after: .appInfo, addition: {
+                Button("Check For Updates") {
+                    SUUpdater.shared()?.checkForUpdates(self)
+                }
+            })
+            #endif
             CommandGroup(replacing: .newItem, addition: {
                 Button("New Post") {
                     createNewLocalPost()
                 }
                 .keyboardShortcut("n", modifiers: [.command])
             })
             CommandGroup(after: .newItem) {
                 Button("Refresh Posts") {
                     DispatchQueue.main.async {
                         model.fetchUserCollections()
                         model.fetchUserPosts()
                     }
                 }
                 .disabled(!model.account.isLoggedIn)
                 .keyboardShortcut("r", modifiers: [.command])
             }
             SidebarCommands()
             #if os(macOS)
             PostCommands(model: model)
             #endif
             CommandGroup(after: .help) {
                 Button("Visit Support Forum") {
                     #if os(macOS)
                     NSWorkspace().open(model.helpURL)
                     #else
                     UIApplication.shared.open(model.helpURL)
                     #endif
                 }
             }
         }
 
         #if os(macOS)
         Settings {
             TabView(selection: $selectedTab) {
                 MacAccountView()
                     .environmentObject(model)
                     .tabItem {
                         Image(systemName: "person.crop.circle")
                         Text("Account")
                     }
                     .tag(0)
                 MacPreferencesView(preferences: model.preferences)
                     .tabItem {
                         Image(systemName: "gear")
                         Text("Preferences")
                     }
                     .tag(1)
+                MacUpdatesView()
+                    .tabItem {
+                        Image(systemName: "arrow.down.circle")
+                        Text("Updates")
+                    }
+                    .tag(2)
             }
-            .frame(minWidth: 300, maxWidth: 300, minHeight: 200, maxHeight: 200)
+            .frame(minWidth: 500, maxWidth: 500, minHeight: 200)
             .padding()
 //            .preferredColorScheme(preferences.selectedColorScheme)    // See PreferencesModel for info.
         }
         #endif
     }
 
     private func createNewLocalPost() {
         withAnimation {
             self.model.selectedPost = nil
         }
         let managedPost = WFAPost(context: LocalStorageManager.persistentContainer.viewContext)
         managedPost.createdDate = Date()
         managedPost.title = ""
         managedPost.body = ""
         managedPost.status = PostStatus.local.rawValue
         managedPost.collectionAlias = nil
         switch model.preferences.font {
         case 1:
             managedPost.appearance = "sans"
         case 2:
             managedPost.appearance = "wrap"
         default:
             managedPost.appearance = "serif"
         }
         if let languageCode = Locale.current.languageCode {
             managedPost.language = languageCode
             managedPost.rtl = Locale.characterDirection(forLanguage: languageCode) == .rightToLeft
         }
         withAnimation {
             self.model.selectedPost = managedPost
         }
     }
 }
diff --git a/Technotes/MacSoftwareUpdater.md b/Technotes/MacSoftwareUpdater.md
new file mode 100644
index 0000000..690f3b8
--- /dev/null
+++ b/Technotes/MacSoftwareUpdater.md
@@ -0,0 +1,66 @@
+#  Mac Software Updater
+
+To make updating the Mac app easy, we're using the [Sparkle framework][1].
+
+This is added to the project via the Swift Package Manager (SPM), but at the time of writing, tagged versions of Sparkle do not yet support
+SPM — the dependency can only be added from a branch or commit. To avoid any surprises arising from updates to the project's `master`
+branch, we're using [WriteFreely's fork of Sparkle][2]. Updates to the forked repository from upstream should be considered dangerous and
+tested thoroughly before merging into `main`.  
+
+WriteFreely for Mac uses the v1.x branch of Sparkle, and is therefore not a sandboxed app.
+
+## Troubleshooting
+
+### If Xcode throws an error when you try to build the project
+
+You may need to reset the package caches:
+
+1. From the **File** menu in Xcode, choose **Swift Packages** → **Reset Package Caches**
+2. Again from the **File** menu, choose **Swift Packages** → **Update to Latest Package Versions**
+
+You should then be able to build and run the Mac target.
+
+### If you can't run `generate_keys` because "Apple cannot check it for malicious software"
+
+There may be a code signing issue with Sparkle. Right-click on `generate_keys` in the Finder and choose Open ([reference][3]). 
+
+## Deploying Updates
+
+To [publish an update to the app][5], you'll need the **Sparkle-for-Swift-Package-Manager.zip** [archive][4] — specifically, you'll need the
+`generate_appcast` tool. Download and de-compress the archive.
+
+You will need some credentials and signing certificates to proceed with this process; speak to the project maintainer if you're responsible for
+creating the update, and confirm you have:
+
+- the app's Developer ID Application certificate (check your Mac's system Keychain)
+- the Sparkle EdDSA signing key (again, check your Mac's system Keychain)
+
+Sign and notarize the app archive, then click on **Export Notarized App** in Xcode's Organizer window. Open the Terminal and navigate to
+where you de-compressed the Sparkle-for-Swift-Package-Manager archive, then create a zip file that preserves symlinks:
+
+```bash
+% ditto -c -k --sequesterRsrc --keepParent  
+```
+
+For example, if you export the notarized app to the desktop, all prior updates are located in `~/Developer/WriteFreely/Updates`, and
+the final archive should be called `WFMac.zip`, you would run:
+
+```bash
+% ditto -c -k --sequesterRsrc --keepParent ~/Desktop/WriteFreely\ for\ Mac.app ~/Developer/WriteFreely/Updates/WFMac.zip
+```
+
+Then, generate an appcast file:
+
+```bash
+% ./bin/generate_appcast ~/Developer/WriteFreely/Updates
+```
+
+Once that's done, upload the appcast.xml and WFMac.zip files to the update distribution server (`files.writefreely.org/apps/mac`)
+and they'll be made available to users.
+
+
+[1]: https://sparkle-project.org
+[2]: https://github.com/writefreely/Sparkle
+[3]: https://github.com/sparkle-project/Sparkle/issues/1701#issuecomment-752249920
+[4]: https://github.com/sparkle-project/Sparkle/releases/tag/1.24.0
+[5]: https://sparkle-project.org/documentation/publishing/
diff --git a/WriteFreely-MultiPlatform.xcodeproj/project.pbxproj b/WriteFreely-MultiPlatform.xcodeproj/project.pbxproj
index d5493aa..4d26050 100644
--- a/WriteFreely-MultiPlatform.xcodeproj/project.pbxproj
+++ b/WriteFreely-MultiPlatform.xcodeproj/project.pbxproj
@@ -1,1216 +1,1245 @@
 // !$*UTF8*$!
 {
 	archiveVersion = 1;
 	classes = {
 	};
 	objectVersion = 52;
 	objects = {
 
 /* Begin PBXBuildFile section */
 		170DFA34251BBC44001D82A0 /* PostEditorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170DFA33251BBC44001D82A0 /* PostEditorModel.swift */; };
 		170DFA35251BBC44001D82A0 /* PostEditorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 170DFA33251BBC44001D82A0 /* PostEditorModel.swift */; };
 		17120DA124E19839002B9F6C /* AccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388D24DDEC7400DEFF9A /* AccountView.swift */; };
 		17120DA224E1985C002B9F6C /* AccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388B24DDC83F00DEFF9A /* AccountModel.swift */; };
 		17120DA324E19A42002B9F6C /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5389124DDED0000DEFF9A /* PreferencesView.swift */; };
 		17120DA724E19D11002B9F6C /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17120DA424E19CBF002B9F6C /* SettingsView.swift */; };
 		17120DA924E1B2F5002B9F6C /* AccountLogoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17120DA824E1B2F5002B9F6C /* AccountLogoutView.swift */; };
 		17120DAA24E1B2F5002B9F6C /* AccountLogoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17120DA824E1B2F5002B9F6C /* AccountLogoutView.swift */; };
 		17120DAC24E1B99F002B9F6C /* AccountLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17120DAB24E1B99F002B9F6C /* AccountLoginView.swift */; };
 		17120DAD24E1B99F002B9F6C /* AccountLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17120DAB24E1B99F002B9F6C /* AccountLoginView.swift */; };
 		17120DB224E1E19C002B9F6C /* SettingsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17120DB124E1E19C002B9F6C /* SettingsHeaderView.swift */; };
 		171BFDFA24D4AF8300888236 /* CollectionListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171BFDF924D4AF8300888236 /* CollectionListView.swift */; };
 		171BFDFB24D4AF8300888236 /* CollectionListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171BFDF924D4AF8300888236 /* CollectionListView.swift */; };
+		172C492E2593981900E20ADF /* MacUpdatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 172C492D2593981900E20ADF /* MacUpdatesView.swift */; };
 		173E19D1254318F600440F0F /* RemoteChangePromptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 173E19D0254318F600440F0F /* RemoteChangePromptView.swift */; };
 		173E19E3254329CC00440F0F /* PostTextEditingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 173E19E2254329CC00440F0F /* PostTextEditingView.swift */; };
 		17466626256C0D0600629997 /* MacEditorTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17466625256C0D0600629997 /* MacEditorTextView.swift */; };
 		17479F152583D8E40072B7FB /* PostEditorSharingPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17479F142583D8E40072B7FB /* PostEditorSharingPicker.swift */; };
 		17480CA5251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17480CA4251272EE00EB7765 /* Bundle+AppVersion.swift */; };
 		17480CA6251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17480CA4251272EE00EB7765 /* Bundle+AppVersion.swift */; };
 		174D313224EC2831006CA9EE /* WriteFreelyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 174D313124EC2831006CA9EE /* WriteFreelyModel.swift */; };
 		174D313324EC2831006CA9EE /* WriteFreelyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 174D313124EC2831006CA9EE /* WriteFreelyModel.swift */; };
 		1753F6AC24E431CC00309365 /* MacPreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1753F6AB24E431CC00309365 /* MacPreferencesView.swift */; };
 		1756AE6E24CB255B00FD7257 /* PostListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756AE6D24CB255B00FD7257 /* PostListModel.swift */; };
 		1756AE6F24CB255B00FD7257 /* PostListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756AE6D24CB255B00FD7257 /* PostListModel.swift */; };
 		1756AE7424CB26FA00FD7257 /* PostCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756AE7324CB26FA00FD7257 /* PostCellView.swift */; };
 		1756AE7524CB26FA00FD7257 /* PostCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756AE7324CB26FA00FD7257 /* PostCellView.swift */; };
 		1756AE7724CB2EDD00FD7257 /* PostEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756AE7624CB2EDD00FD7257 /* PostEditorView.swift */; };
 		1756AE7A24CB65DF00FD7257 /* PostListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756AE7924CB65DF00FD7257 /* PostListView.swift */; };
 		1756AE7B24CB65DF00FD7257 /* PostListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756AE7924CB65DF00FD7257 /* PostListView.swift */; };
 		1756AE8124CB844500FD7257 /* View+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756AE8024CB844500FD7257 /* View+Keyboard.swift */; };
 		1756DBB324FECDBB00207AB8 /* PostEditorStatusToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756DBB224FECDBB00207AB8 /* PostEditorStatusToolbarView.swift */; };
 		1756DBB424FECDBB00207AB8 /* PostEditorStatusToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756DBB224FECDBB00207AB8 /* PostEditorStatusToolbarView.swift */; };
 		1756DBB724FED3A400207AB8 /* LocalStorageModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1756DBB524FED3A400207AB8 /* LocalStorageModel.xcdatamodeld */; };
 		1756DBB824FED3A400207AB8 /* LocalStorageModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1756DBB524FED3A400207AB8 /* LocalStorageModel.xcdatamodeld */; };
 		1756DBBA24FED45500207AB8 /* LocalStorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756DBB924FED45500207AB8 /* LocalStorageManager.swift */; };
 		1756DBBB24FED45500207AB8 /* LocalStorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756DBB924FED45500207AB8 /* LocalStorageManager.swift */; };
 		1756DC0124FEE18400207AB8 /* WFACollection+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756DBFF24FEE18400207AB8 /* WFACollection+CoreDataClass.swift */; };
 		1756DC0224FEE18400207AB8 /* WFACollection+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756DBFF24FEE18400207AB8 /* WFACollection+CoreDataClass.swift */; };
 		1756DC0324FEE18400207AB8 /* WFACollection+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756DC0024FEE18400207AB8 /* WFACollection+CoreDataProperties.swift */; };
 		1756DC0424FEE18400207AB8 /* WFACollection+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1756DC0024FEE18400207AB8 /* WFACollection+CoreDataProperties.swift */; };
 		1765F62A24E18EA200C9EBF0 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1765F62924E18EA200C9EBF0 /* SidebarView.swift */; };
 		1765F62B24E18EA200C9EBF0 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1765F62924E18EA200C9EBF0 /* SidebarView.swift */; };
 		17681E412519410E00D394AE /* UINavigationController+Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17681E402519410E00D394AE /* UINavigationController+Appearance.swift */; };
 		1780F6EF25895EDB00FE45FF /* PostCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1780F6EE25895EDB00FE45FF /* PostCommands.swift */; };
+		17A4FEDA25924AF70037E96B /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 17A4FED925924AF70037E96B /* Sparkle */; };
+		17A4FEED25927E730037E96B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A4FEEC25927E730037E96B /* AppDelegate.swift */; };
 		17A5388824DDA31F00DEFF9A /* MacAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388724DDA31F00DEFF9A /* MacAccountView.swift */; };
 		17A5388C24DDC83F00DEFF9A /* AccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388B24DDC83F00DEFF9A /* AccountModel.swift */; };
 		17A5388F24DDEC7400DEFF9A /* AccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388D24DDEC7400DEFF9A /* AccountView.swift */; };
 		17A5389324DDED0000DEFF9A /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5389124DDED0000DEFF9A /* PreferencesView.swift */; };
 		17A67CAF251A5DD7002F163D /* PostEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A67CAE251A5DD7002F163D /* PostEditorView.swift */; };
 		17AD0A5E25489E810057D763 /* PostTitleTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17AD0A5D25489E810057D763 /* PostTitleTextView.swift */; };
 		17AD0A6425489E900057D763 /* PostBodyTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17AD0A6325489E900057D763 /* PostBodyTextView.swift */; };
 		17B3E965250FAA9000EE9748 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17B3E964250FAA9000EE9748 /* LaunchScreen.storyboard */; };
 		17B5103B2515448D00E9631F /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 17B5103A2515448D00E9631F /* Credits.rtf */; };
 		17B996D82502D23E0017B536 /* WFAPost+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17B996D62502D23E0017B536 /* WFAPost+CoreDataClass.swift */; };
 		17B996D92502D23E0017B536 /* WFAPost+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17B996D62502D23E0017B536 /* WFAPost+CoreDataClass.swift */; };
 		17B996DA2502D23E0017B536 /* WFAPost+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17B996D72502D23E0017B536 /* WFAPost+CoreDataProperties.swift */; };
 		17B996DB2502D23E0017B536 /* WFAPost+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17B996D72502D23E0017B536 /* WFAPost+CoreDataProperties.swift */; };
 		17BC618A25715318003363CA /* ActivePostToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17BC617825715068003363CA /* ActivePostToolbarView.swift */; };
 		17C42E622507D8E600072984 /* PostStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17C42E612507D8E600072984 /* PostStatus.swift */; };
 		17C42E632507D8E600072984 /* PostStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17C42E612507D8E600072984 /* PostStatus.swift */; };
 		17C42E652509237800072984 /* PostListFilteredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17C42E642509237800072984 /* PostListFilteredView.swift */; };
 		17C42E662509237800072984 /* PostListFilteredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17C42E642509237800072984 /* PostListFilteredView.swift */; };
 		17C42E70250AA12300072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17C42E6F250AA12200072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift */; };
 		17C42E71250AAFD500072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17C42E6F250AA12200072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift */; };
 		17D435E824E3128F0036B539 /* PreferencesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D435E724E3128F0036B539 /* PreferencesModel.swift */; };
 		17D435E924E3128F0036B539 /* PreferencesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D435E724E3128F0036B539 /* PreferencesModel.swift */; };
 		17D4F36C2514EE2F00517CE6 /* LoraGX.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 17D4F36B2514EE2F00517CE6 /* LoraGX.ttf */; };
 		17D4F36D2514EE2F00517CE6 /* LoraGX.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 17D4F36B2514EE2F00517CE6 /* LoraGX.ttf */; };
 		17D4F39E2514F0E500517CE6 /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 17D4F39D2514F0E500517CE6 /* OpenSans-Regular.ttf */; };
 		17D4F39F2514F0E500517CE6 /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 17D4F39D2514F0E500517CE6 /* OpenSans-Regular.ttf */; };
 		17D4F3A52514F1E900517CE6 /* Hack-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 17D4F3A42514F1E900517CE6 /* Hack-Regular.ttf */; };
 		17D4F3A62514F1E900517CE6 /* Hack-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 17D4F3A42514F1E900517CE6 /* Hack-Regular.ttf */; };
 		17DF329D24C87D3500BCE2E3 /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DF329C24C87D3500BCE2E3 /* Tests_iOS.swift */; };
 		17DF32A824C87D3500BCE2E3 /* Tests_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DF32A724C87D3500BCE2E3 /* Tests_macOS.swift */; };
 		17DF32AA24C87D3500BCE2E3 /* WriteFreely_MultiPlatformApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DF328124C87D3300BCE2E3 /* WriteFreely_MultiPlatformApp.swift */; };
 		17DF32AB24C87D3500BCE2E3 /* WriteFreely_MultiPlatformApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DF328124C87D3300BCE2E3 /* WriteFreely_MultiPlatformApp.swift */; };
 		17DF32AC24C87D3500BCE2E3 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DF328224C87D3300BCE2E3 /* ContentView.swift */; };
 		17DF32AD24C87D3500BCE2E3 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DF328224C87D3300BCE2E3 /* ContentView.swift */; };
 		17DF32AE24C87D3500BCE2E3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17DF328324C87D3500BCE2E3 /* Assets.xcassets */; };
 		17DF32AF24C87D3500BCE2E3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17DF328324C87D3500BCE2E3 /* Assets.xcassets */; };
 		17DF32C024C87D7B00BCE2E3 /* WriteFreely in Frameworks */ = {isa = PBXBuildFile; productRef = 17DF32BF24C87D7B00BCE2E3 /* WriteFreely */; };
 		17DF32C324C87D8D00BCE2E3 /* WriteFreely in Frameworks */ = {isa = PBXBuildFile; productRef = 17DF32C224C87D8D00BCE2E3 /* WriteFreely */; };
 		17DF32D524C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DF32D424C8CA3400BCE2E3 /* PostStatusBadgeView.swift */; };
 		17DF32D624C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DF32D424C8CA3400BCE2E3 /* PostStatusBadgeView.swift */; };
 		17DFDE87251D309400A25F31 /* Hack-License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE84251D309400A25F31 /* Hack-License.txt */; };
 		17DFDE88251D309400A25F31 /* Hack-License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE84251D309400A25F31 /* Hack-License.txt */; };
 		17DFDE89251D309400A25F31 /* Lora-Cyrillic-OFL.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */; };
 		17DFDE8A251D309400A25F31 /* Lora-Cyrillic-OFL.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */; };
 		17DFDE8B251D309400A25F31 /* OpenSans-License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE86251D309400A25F31 /* OpenSans-License.txt */; };
 		17DFDE8C251D309400A25F31 /* OpenSans-License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 17DFDE86251D309400A25F31 /* OpenSans-License.txt */; };
 		17E5DF8A2543610700DCDC9B /* PostTextEditingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17E5DF892543610700DCDC9B /* PostTextEditingView.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
 		17DF329924C87D3500BCE2E3 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 17DF327C24C87D3300BCE2E3 /* Project object */;
 			proxyType = 1;
 			remoteGlobalIDString = 17DF328724C87D3500BCE2E3;
 			remoteInfo = "WriteFreely-MultiPlatform (iOS)";
 		};
 		17DF32A424C87D3500BCE2E3 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 17DF327C24C87D3300BCE2E3 /* Project object */;
 			proxyType = 1;
 			remoteGlobalIDString = 17DF328F24C87D3500BCE2E3;
 			remoteInfo = "WriteFreely-MultiPlatform (macOS)";
 		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
 		1709ADDF251B9A110053AF79 /* EditorLaunchingPolicy.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = EditorLaunchingPolicy.md; sourceTree = ""; };
 		170DFA33251BBC44001D82A0 /* PostEditorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostEditorModel.swift; sourceTree = ""; };
 		17120DA424E19CBF002B9F6C /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; };
 		17120DA824E1B2F5002B9F6C /* AccountLogoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountLogoutView.swift; sourceTree = ""; };
 		17120DAB24E1B99F002B9F6C /* AccountLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountLoginView.swift; sourceTree = ""; };
 		17120DB124E1E19C002B9F6C /* SettingsHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeaderView.swift; sourceTree = ""; };
 		171BFDF924D4AF8300888236 /* CollectionListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionListView.swift; sourceTree = ""; };
+		172C492D2593981900E20ADF /* MacUpdatesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacUpdatesView.swift; sourceTree = ""; };
 		173E19D0254318F600440F0F /* RemoteChangePromptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteChangePromptView.swift; sourceTree = ""; };
 		173E19E2254329CC00440F0F /* PostTextEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTextEditingView.swift; sourceTree = ""; };
 		17466625256C0D0600629997 /* MacEditorTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacEditorTextView.swift; sourceTree = ""; };
 		17479F142583D8E40072B7FB /* PostEditorSharingPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostEditorSharingPicker.swift; sourceTree = ""; };
 		17480CA4251272EE00EB7765 /* Bundle+AppVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+AppVersion.swift"; sourceTree = ""; };
 		174D313124EC2831006CA9EE /* WriteFreelyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteFreelyModel.swift; sourceTree = ""; };
 		1753F6AB24E431CC00309365 /* MacPreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacPreferencesView.swift; sourceTree = ""; };
 		1756AE6D24CB255B00FD7257 /* PostListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostListModel.swift; sourceTree = ""; };
 		1756AE7324CB26FA00FD7257 /* PostCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostCellView.swift; sourceTree = ""; };
 		1756AE7624CB2EDD00FD7257 /* PostEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostEditorView.swift; sourceTree = ""; };
 		1756AE7924CB65DF00FD7257 /* PostListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostListView.swift; sourceTree = ""; };
 		1756AE8024CB844500FD7257 /* View+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Keyboard.swift"; sourceTree = ""; };
 		1756DBB224FECDBB00207AB8 /* PostEditorStatusToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostEditorStatusToolbarView.swift; sourceTree = ""; };
 		1756DBB624FED3A400207AB8 /* LocalStorageModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = LocalStorageModel.xcdatamodel; sourceTree = ""; };
 		1756DBB924FED45500207AB8 /* LocalStorageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalStorageManager.swift; sourceTree = ""; };
 		1756DBFF24FEE18400207AB8 /* WFACollection+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WFACollection+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; };
 		1756DC0024FEE18400207AB8 /* WFACollection+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WFACollection+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; };
 		1765F62924E18EA200C9EBF0 /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = ""; };
 		17681E402519410E00D394AE /* UINavigationController+Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Appearance.swift"; sourceTree = ""; };
 		1780F6EE25895EDB00FE45FF /* PostCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostCommands.swift; sourceTree = ""; };
+		17A4FEDF25924E810037E96B /* MacSoftwareUpdater.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = MacSoftwareUpdater.md; sourceTree = ""; };
+		17A4FEEC25927E730037E96B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
 		17A5388724DDA31F00DEFF9A /* MacAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacAccountView.swift; sourceTree = ""; };
 		17A5388B24DDC83F00DEFF9A /* AccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountModel.swift; sourceTree = ""; };
 		17A5388D24DDEC7400DEFF9A /* AccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountView.swift; sourceTree = ""; };
 		17A5389124DDED0000DEFF9A /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = ""; };
 		17A67CAE251A5DD7002F163D /* PostEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostEditorView.swift; sourceTree = ""; };
 		17AD0A5D25489E810057D763 /* PostTitleTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTitleTextView.swift; sourceTree = ""; };
 		17AD0A6325489E900057D763 /* PostBodyTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostBodyTextView.swift; sourceTree = ""; };
 		17B3E964250FAA9000EE9748 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
 		17B5103A2515448D00E9631F /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; };
+		17B68D4F25A4FED2005ED37C /* Sparkle-License.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Sparkle-License.txt"; sourceTree = ""; };
 		17B996D62502D23E0017B536 /* WFAPost+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WFAPost+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; };
 		17B996D72502D23E0017B536 /* WFAPost+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WFAPost+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; };
 		17BC617825715068003363CA /* ActivePostToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivePostToolbarView.swift; sourceTree = ""; };
 		17C42E612507D8E600072984 /* PostStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostStatus.swift; sourceTree = ""; };
 		17C42E642509237800072984 /* PostListFilteredView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostListFilteredView.swift; sourceTree = ""; };
 		17C42E6F250AA12200072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+ExecuteAndMergeChanges.swift"; sourceTree = ""; };
 		17D435E724E3128F0036B539 /* PreferencesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesModel.swift; sourceTree = ""; };
 		17D4F36B2514EE2F00517CE6 /* LoraGX.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = LoraGX.ttf; sourceTree = ""; };
 		17D4F39D2514F0E500517CE6 /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "OpenSans-Regular.ttf"; sourceTree = ""; };
 		17D4F3A42514F1E900517CE6 /* Hack-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Hack-Regular.ttf"; sourceTree = ""; };
 		17DF328124C87D3300BCE2E3 /* WriteFreely_MultiPlatformApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteFreely_MultiPlatformApp.swift; sourceTree = ""; };
 		17DF328224C87D3300BCE2E3 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
 		17DF328324C87D3500BCE2E3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
 		17DF328824C87D3500BCE2E3 /* WriteFreely-MultiPlatform.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WriteFreely-MultiPlatform.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		17DF328B24C87D3500BCE2E3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
 		17DF329024C87D3500BCE2E3 /* WriteFreely for Mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WriteFreely for Mac.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		17DF329224C87D3500BCE2E3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
 		17DF329324C87D3500BCE2E3 /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; };
 		17DF329824C87D3500BCE2E3 /* Tests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
 		17DF329C24C87D3500BCE2E3 /* Tests_iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_iOS.swift; sourceTree = ""; };
 		17DF329E24C87D3500BCE2E3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
 		17DF32A324C87D3500BCE2E3 /* Tests macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
 		17DF32A724C87D3500BCE2E3 /* Tests_macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests_macOS.swift; sourceTree = ""; };
 		17DF32A924C87D3500BCE2E3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
 		17DF32C624C884FF00BCE2E3 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
 		17DF32C724C8853700BCE2E3 /* CODE_OF_CONDUCT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CODE_OF_CONDUCT.md; sourceTree = ""; };
 		17DF32C824C8854B00BCE2E3 /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = ""; };
 		17DF32C924C8855E00BCE2E3 /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; };
 		17DF32CA24C8856C00BCE2E3 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = ""; };
 		17DF32D424C8CA3400BCE2E3 /* PostStatusBadgeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostStatusBadgeView.swift; sourceTree = ""; };
 		17DFDE84251D309400A25F31 /* Hack-License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Hack-License.txt"; sourceTree = ""; };
 		17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Lora-Cyrillic-OFL.txt"; sourceTree = ""; };
 		17DFDE86251D309400A25F31 /* OpenSans-License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "OpenSans-License.txt"; sourceTree = ""; };
 		17E5DF892543610700DCDC9B /* PostTextEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTextEditingView.swift; sourceTree = ""; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
 		17DF328524C87D3500BCE2E3 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 				17DF32C024C87D7B00BCE2E3 /* WriteFreely in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF328D24C87D3500BCE2E3 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 				17DF32C324C87D8D00BCE2E3 /* WriteFreely in Frameworks */,
+				17A4FEDA25924AF70037E96B /* Sparkle in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF329524C87D3500BCE2E3 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF32A024C87D3500BCE2E3 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
 		1709ADDE251B99D40053AF79 /* Technotes */ = {
 			isa = PBXGroup;
 			children = (
 				1709ADDF251B9A110053AF79 /* EditorLaunchingPolicy.md */,
+				17A4FEDF25924E810037E96B /* MacSoftwareUpdater.md */,
 			);
 			path = Technotes;
 			sourceTree = "";
 		};
 		17120DA624E19CE2002B9F6C /* Settings */ = {
 			isa = PBXGroup;
 			children = (
 				17120DB124E1E19C002B9F6C /* SettingsHeaderView.swift */,
 				17120DA424E19CBF002B9F6C /* SettingsView.swift */,
 			);
 			path = Settings;
 			sourceTree = "";
 		};
 		1739B8D324EAFAB700DA7421 /* PostEditor */ = {
 			isa = PBXGroup;
 			children = (
 				170DFA33251BBC44001D82A0 /* PostEditorModel.swift */,
 				1756DBB224FECDBB00207AB8 /* PostEditorStatusToolbarView.swift */,
 			);
 			path = PostEditor;
 			sourceTree = "";
 		};
 		1756AE7F24CB841200FD7257 /* Extensions */ = {
 			isa = PBXGroup;
 			children = (
 				17C42E6F250AA12200072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift */,
 				17480CA4251272EE00EB7765 /* Bundle+AppVersion.swift */,
 			);
 			path = Extensions;
 			sourceTree = "";
 		};
 		1762DCB124EB07680019C4EB /* Models */ = {
 			isa = PBXGroup;
 			children = (
 				1756DBFF24FEE18400207AB8 /* WFACollection+CoreDataClass.swift */,
 				1756DC0024FEE18400207AB8 /* WFACollection+CoreDataProperties.swift */,
 				17B996D62502D23E0017B536 /* WFAPost+CoreDataClass.swift */,
 				17B996D72502D23E0017B536 /* WFAPost+CoreDataProperties.swift */,
 				17C42E612507D8E600072984 /* PostStatus.swift */,
 				174D313124EC2831006CA9EE /* WriteFreelyModel.swift */,
 				1756DBB524FED3A400207AB8 /* LocalStorageModel.xcdatamodeld */,
 			);
 			path = Models;
 			sourceTree = "";
 		};
 		1765F62C24E1924800C9EBF0 /* Preferences */ = {
 			isa = PBXGroup;
 			children = (
 				17D435E724E3128F0036B539 /* PreferencesModel.swift */,
 				17A5389124DDED0000DEFF9A /* PreferencesView.swift */,
 			);
 			path = Preferences;
 			sourceTree = "";
 		};
 		17681E3F251940F200D394AE /* Extensions */ = {
 			isa = PBXGroup;
 			children = (
 				1756AE8024CB844500FD7257 /* View+Keyboard.swift */,
 				17681E402519410E00D394AE /* UINavigationController+Appearance.swift */,
 			);
 			path = Extensions;
 			sourceTree = "";
 		};
 		17A5388924DDA50500DEFF9A /* Settings */ = {
 			isa = PBXGroup;
 			children = (
 				17A5388724DDA31F00DEFF9A /* MacAccountView.swift */,
 				1753F6AB24E431CC00309365 /* MacPreferencesView.swift */,
+				172C492D2593981900E20ADF /* MacUpdatesView.swift */,
 			);
 			path = Settings;
 			sourceTree = "";
 		};
 		17A67CAB251A5D7E002F163D /* PostEditor */ = {
 			isa = PBXGroup;
 			children = (
 				1756AE7624CB2EDD00FD7257 /* PostEditorView.swift */,
 				173E19D0254318F600440F0F /* RemoteChangePromptView.swift */,
 				173E19E2254329CC00440F0F /* PostTextEditingView.swift */,
 				17AD0A5D25489E810057D763 /* PostTitleTextView.swift */,
 				17AD0A6325489E900057D763 /* PostBodyTextView.swift */,
 			);
 			path = PostEditor;
 			sourceTree = "";
 		};
 		17A67CAC251A5D8D002F163D /* PostEditor */ = {
 			isa = PBXGroup;
 			children = (
 				17479F142583D8E40072B7FB /* PostEditorSharingPicker.swift */,
 				17A67CAE251A5DD7002F163D /* PostEditorView.swift */,
 				17E5DF892543610700DCDC9B /* PostTextEditingView.swift */,
 				17466625256C0D0600629997 /* MacEditorTextView.swift */,
 			);
 			path = PostEditor;
 			sourceTree = "";
 		};
 		17BC617725715042003363CA /* Navigation */ = {
 			isa = PBXGroup;
 			children = (
 				17BC617825715068003363CA /* ActivePostToolbarView.swift */,
 				1780F6EE25895EDB00FE45FF /* PostCommands.swift */,
 			);
 			path = Navigation;
 			sourceTree = "";
 		};
 		17D4F3722514EE4400517CE6 /* Resources */ = {
 			isa = PBXGroup;
 			children = (
 				17DFDE83251D309400A25F31 /* Licenses */,
 				17D4F3A42514F1E900517CE6 /* Hack-Regular.ttf */,
 				17D4F39D2514F0E500517CE6 /* OpenSans-Regular.ttf */,
 				17D4F36B2514EE2F00517CE6 /* LoraGX.ttf */,
 			);
 			path = Resources;
 			sourceTree = "";
 		};
 		17DF327B24C87D3300BCE2E3 = {
 			isa = PBXGroup;
 			children = (
 				17DF32C624C884FF00BCE2E3 /* README.md */,
 				17DF32C924C8855E00BCE2E3 /* LICENSE.md */,
 				17DF32CA24C8856C00BCE2E3 /* CHANGELOG.md */,
 				17DF32C724C8853700BCE2E3 /* CODE_OF_CONDUCT.md */,
 				17DF32C824C8854B00BCE2E3 /* CONTRIBUTING.md */,
 				1709ADDE251B99D40053AF79 /* Technotes */,
 				17DF328024C87D3300BCE2E3 /* Shared */,
 				17DF328A24C87D3500BCE2E3 /* iOS */,
 				17DF329124C87D3500BCE2E3 /* macOS */,
 				17DF329B24C87D3500BCE2E3 /* Tests iOS */,
 				17DF32A624C87D3500BCE2E3 /* Tests macOS */,
 				17DF328924C87D3500BCE2E3 /* Products */,
 				17DF32C124C87D8D00BCE2E3 /* Frameworks */,
 			);
 			sourceTree = "";
 		};
 		17DF328024C87D3300BCE2E3 /* Shared */ = {
 			isa = PBXGroup;
 			children = (
 				17DF328124C87D3300BCE2E3 /* WriteFreely_MultiPlatformApp.swift */,
 				1756DBB924FED45500207AB8 /* LocalStorageManager.swift */,
 				17DF328324C87D3500BCE2E3 /* Assets.xcassets */,
 				17DF32D024C8B75C00BCE2E3 /* Account */,
 				1756AE7F24CB841200FD7257 /* Extensions */,
 				1762DCB124EB07680019C4EB /* Models */,
 				17DF32CC24C8B72300BCE2E3 /* Navigation */,
 				1739B8D324EAFAB700DA7421 /* PostEditor */,
 				17DF32D124C8B78500BCE2E3 /* PostList */,
 				17DF32D224C8B78D00BCE2E3 /* PostCollection */,
 				1765F62C24E1924800C9EBF0 /* Preferences */,
 				17D4F3722514EE4400517CE6 /* Resources */,
 			);
 			path = Shared;
 			sourceTree = "";
 		};
 		17DF328924C87D3500BCE2E3 /* Products */ = {
 			isa = PBXGroup;
 			children = (
 				17DF328824C87D3500BCE2E3 /* WriteFreely-MultiPlatform.app */,
 				17DF329024C87D3500BCE2E3 /* WriteFreely for Mac.app */,
 				17DF329824C87D3500BCE2E3 /* Tests iOS.xctest */,
 				17DF32A324C87D3500BCE2E3 /* Tests macOS.xctest */,
 			);
 			name = Products;
 			sourceTree = "";
 		};
 		17DF328A24C87D3500BCE2E3 /* iOS */ = {
 			isa = PBXGroup;
 			children = (
 				17DF328B24C87D3500BCE2E3 /* Info.plist */,
 				17B3E964250FAA9000EE9748 /* LaunchScreen.storyboard */,
 				17681E3F251940F200D394AE /* Extensions */,
 				17A67CAB251A5D7E002F163D /* PostEditor */,
 				17120DA624E19CE2002B9F6C /* Settings */,
 			);
 			path = iOS;
 			sourceTree = "";
 		};
 		17DF329124C87D3500BCE2E3 /* macOS */ = {
 			isa = PBXGroup;
 			children = (
 				17DF329224C87D3500BCE2E3 /* Info.plist */,
 				17DF329324C87D3500BCE2E3 /* macOS.entitlements */,
+				17A4FEEC25927E730037E96B /* AppDelegate.swift */,
 				17BC617725715042003363CA /* Navigation */,
 				17A67CAC251A5D8D002F163D /* PostEditor */,
 				17A5388924DDA50500DEFF9A /* Settings */,
 				17B5103A2515448D00E9631F /* Credits.rtf */,
 			);
 			path = macOS;
 			sourceTree = "";
 		};
 		17DF329B24C87D3500BCE2E3 /* Tests iOS */ = {
 			isa = PBXGroup;
 			children = (
 				17DF329C24C87D3500BCE2E3 /* Tests_iOS.swift */,
 				17DF329E24C87D3500BCE2E3 /* Info.plist */,
 			);
 			path = "Tests iOS";
 			sourceTree = "";
 		};
 		17DF32A624C87D3500BCE2E3 /* Tests macOS */ = {
 			isa = PBXGroup;
 			children = (
 				17DF32A724C87D3500BCE2E3 /* Tests_macOS.swift */,
 				17DF32A924C87D3500BCE2E3 /* Info.plist */,
 			);
 			path = "Tests macOS";
 			sourceTree = "";
 		};
 		17DF32C124C87D8D00BCE2E3 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
 			);
 			name = Frameworks;
 			sourceTree = "";
 		};
 		17DF32CC24C8B72300BCE2E3 /* Navigation */ = {
 			isa = PBXGroup;
 			children = (
 				17DF328224C87D3300BCE2E3 /* ContentView.swift */,
 				1765F62924E18EA200C9EBF0 /* SidebarView.swift */,
 			);
 			path = Navigation;
 			sourceTree = "";
 		};
 		17DF32D024C8B75C00BCE2E3 /* Account */ = {
 			isa = PBXGroup;
 			children = (
 				17A5388B24DDC83F00DEFF9A /* AccountModel.swift */,
 				17120DAB24E1B99F002B9F6C /* AccountLoginView.swift */,
 				17120DA824E1B2F5002B9F6C /* AccountLogoutView.swift */,
 				17A5388D24DDEC7400DEFF9A /* AccountView.swift */,
 			);
 			path = Account;
 			sourceTree = "";
 		};
 		17DF32D124C8B78500BCE2E3 /* PostList */ = {
 			isa = PBXGroup;
 			children = (
 				1756AE7324CB26FA00FD7257 /* PostCellView.swift */,
 				1756AE6D24CB255B00FD7257 /* PostListModel.swift */,
 				1756AE7924CB65DF00FD7257 /* PostListView.swift */,
 				17DF32D424C8CA3400BCE2E3 /* PostStatusBadgeView.swift */,
 				17C42E642509237800072984 /* PostListFilteredView.swift */,
 			);
 			path = PostList;
 			sourceTree = "";
 		};
 		17DF32D224C8B78D00BCE2E3 /* PostCollection */ = {
 			isa = PBXGroup;
 			children = (
 				171BFDF924D4AF8300888236 /* CollectionListView.swift */,
 			);
 			path = PostCollection;
 			sourceTree = "";
 		};
 		17DFDE83251D309400A25F31 /* Licenses */ = {
 			isa = PBXGroup;
 			children = (
+				17B68D4F25A4FED2005ED37C /* Sparkle-License.txt */,
 				17DFDE84251D309400A25F31 /* Hack-License.txt */,
 				17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */,
 				17DFDE86251D309400A25F31 /* OpenSans-License.txt */,
 			);
 			path = Licenses;
 			sourceTree = "";
 		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
 		17DF328724C87D3500BCE2E3 /* WriteFreely-MultiPlatform (iOS) */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 17DF32B224C87D3500BCE2E3 /* Build configuration list for PBXNativeTarget "WriteFreely-MultiPlatform (iOS)" */;
 			buildPhases = (
 				17DF328424C87D3500BCE2E3 /* Sources */,
 				17DF328524C87D3500BCE2E3 /* Frameworks */,
 				17DF328624C87D3500BCE2E3 /* Resources */,
 				17DF32C424C87E6700BCE2E3 /* ShellScript */,
 			);
 			buildRules = (
 			);
 			dependencies = (
 			);
 			name = "WriteFreely-MultiPlatform (iOS)";
 			packageProductDependencies = (
 				17DF32BF24C87D7B00BCE2E3 /* WriteFreely */,
 			);
 			productName = "WriteFreely-MultiPlatform (iOS)";
 			productReference = 17DF328824C87D3500BCE2E3 /* WriteFreely-MultiPlatform.app */;
 			productType = "com.apple.product-type.application";
 		};
 		17DF328F24C87D3500BCE2E3 /* WriteFreely-MultiPlatform (macOS) */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 17DF32B524C87D3500BCE2E3 /* Build configuration list for PBXNativeTarget "WriteFreely-MultiPlatform (macOS)" */;
 			buildPhases = (
 				17DF328C24C87D3500BCE2E3 /* Sources */,
 				17DF328D24C87D3500BCE2E3 /* Frameworks */,
 				17DF328E24C87D3500BCE2E3 /* Resources */,
 				17DF32C524C87FDB00BCE2E3 /* ShellScript */,
 			);
 			buildRules = (
 			);
 			dependencies = (
 			);
 			name = "WriteFreely-MultiPlatform (macOS)";
 			packageProductDependencies = (
 				17DF32C224C87D8D00BCE2E3 /* WriteFreely */,
+				17A4FED925924AF70037E96B /* Sparkle */,
 			);
 			productName = "WriteFreely-MultiPlatform (macOS)";
 			productReference = 17DF329024C87D3500BCE2E3 /* WriteFreely for Mac.app */;
 			productType = "com.apple.product-type.application";
 		};
 		17DF329724C87D3500BCE2E3 /* Tests iOS */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 17DF32B824C87D3500BCE2E3 /* Build configuration list for PBXNativeTarget "Tests iOS" */;
 			buildPhases = (
 				17DF329424C87D3500BCE2E3 /* Sources */,
 				17DF329524C87D3500BCE2E3 /* Frameworks */,
 				17DF329624C87D3500BCE2E3 /* Resources */,
 			);
 			buildRules = (
 			);
 			dependencies = (
 				17DF329A24C87D3500BCE2E3 /* PBXTargetDependency */,
 			);
 			name = "Tests iOS";
 			productName = "Tests iOS";
 			productReference = 17DF329824C87D3500BCE2E3 /* Tests iOS.xctest */;
 			productType = "com.apple.product-type.bundle.ui-testing";
 		};
 		17DF32A224C87D3500BCE2E3 /* Tests macOS */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 17DF32BB24C87D3500BCE2E3 /* Build configuration list for PBXNativeTarget "Tests macOS" */;
 			buildPhases = (
 				17DF329F24C87D3500BCE2E3 /* Sources */,
 				17DF32A024C87D3500BCE2E3 /* Frameworks */,
 				17DF32A124C87D3500BCE2E3 /* Resources */,
 			);
 			buildRules = (
 			);
 			dependencies = (
 				17DF32A524C87D3500BCE2E3 /* PBXTargetDependency */,
 			);
 			name = "Tests macOS";
 			productName = "Tests macOS";
 			productReference = 17DF32A324C87D3500BCE2E3 /* Tests macOS.xctest */;
 			productType = "com.apple.product-type.bundle.ui-testing";
 		};
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
 		17DF327C24C87D3300BCE2E3 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
 				LastSwiftUpdateCheck = 1200;
 				LastUpgradeCheck = 1200;
 				TargetAttributes = {
 					17DF328724C87D3500BCE2E3 = {
 						CreatedOnToolsVersion = 12.0;
 					};
 					17DF328F24C87D3500BCE2E3 = {
 						CreatedOnToolsVersion = 12.0;
 					};
 					17DF329724C87D3500BCE2E3 = {
 						CreatedOnToolsVersion = 12.0;
 						TestTargetID = 17DF328724C87D3500BCE2E3;
 					};
 					17DF32A224C87D3500BCE2E3 = {
 						CreatedOnToolsVersion = 12.0;
 						TestTargetID = 17DF328F24C87D3500BCE2E3;
 					};
 				};
 			};
 			buildConfigurationList = 17DF327F24C87D3300BCE2E3 /* Build configuration list for PBXProject "WriteFreely-MultiPlatform" */;
 			compatibilityVersion = "Xcode 9.3";
 			developmentRegion = en;
 			hasScannedForEncodings = 0;
 			knownRegions = (
 				en,
 				Base,
 			);
 			mainGroup = 17DF327B24C87D3300BCE2E3;
 			packageReferences = (
 				17DF32BE24C87D7B00BCE2E3 /* XCRemoteSwiftPackageReference "writefreely-swift" */,
+				17A4FED825924AF70037E96B /* XCRemoteSwiftPackageReference "Sparkle" */,
 			);
 			productRefGroup = 17DF328924C87D3500BCE2E3 /* Products */;
 			projectDirPath = "";
 			projectRoot = "";
 			targets = (
 				17DF328724C87D3500BCE2E3 /* WriteFreely-MultiPlatform (iOS) */,
 				17DF328F24C87D3500BCE2E3 /* WriteFreely-MultiPlatform (macOS) */,
 				17DF329724C87D3500BCE2E3 /* Tests iOS */,
 				17DF32A224C87D3500BCE2E3 /* Tests macOS */,
 			);
 		};
 /* End PBXProject section */
 
 /* Begin PBXResourcesBuildPhase section */
 		17DF328624C87D3500BCE2E3 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 				17B3E965250FAA9000EE9748 /* LaunchScreen.storyboard in Resources */,
 				17DFDE8B251D309400A25F31 /* OpenSans-License.txt in Resources */,
 				17DF32AE24C87D3500BCE2E3 /* Assets.xcassets in Resources */,
 				17D4F39E2514F0E500517CE6 /* OpenSans-Regular.ttf in Resources */,
 				17D4F36C2514EE2F00517CE6 /* LoraGX.ttf in Resources */,
 				17D4F3A52514F1E900517CE6 /* Hack-Regular.ttf in Resources */,
 				17DFDE89251D309400A25F31 /* Lora-Cyrillic-OFL.txt in Resources */,
 				17DFDE87251D309400A25F31 /* Hack-License.txt in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF328E24C87D3500BCE2E3 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 				17DF32AF24C87D3500BCE2E3 /* Assets.xcassets in Resources */,
 				17DFDE8C251D309400A25F31 /* OpenSans-License.txt in Resources */,
 				17B5103B2515448D00E9631F /* Credits.rtf in Resources */,
 				17D4F39F2514F0E500517CE6 /* OpenSans-Regular.ttf in Resources */,
 				17D4F3A62514F1E900517CE6 /* Hack-Regular.ttf in Resources */,
 				17D4F36D2514EE2F00517CE6 /* LoraGX.ttf in Resources */,
 				17DFDE8A251D309400A25F31 /* Lora-Cyrillic-OFL.txt in Resources */,
 				17DFDE88251D309400A25F31 /* Hack-License.txt in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF329624C87D3500BCE2E3 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF32A124C87D3500BCE2E3 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
 		17DF32C424C87E6700BCE2E3 /* ShellScript */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputFileListPaths = (
 			);
 			inputPaths = (
 			);
 			outputFileListPaths = (
 			);
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellScript = "# Run SwiftLint on builds\nif which swiftlint >/dev/null; then\n  swiftlint\nelse\n  echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
 		};
 		17DF32C524C87FDB00BCE2E3 /* ShellScript */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputFileListPaths = (
 			);
 			inputPaths = (
 			);
 			outputFileListPaths = (
 			);
 			outputPaths = (
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellScript = "# Run SwiftLint on builds\nif which swiftlint >/dev/null; then\n  swiftlint\nelse\n  echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
 		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
 		17DF328424C87D3500BCE2E3 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 				17DF32AC24C87D3500BCE2E3 /* ContentView.swift in Sources */,
 				173E19D1254318F600440F0F /* RemoteChangePromptView.swift in Sources */,
 				17C42E622507D8E600072984 /* PostStatus.swift in Sources */,
 				1756DBBA24FED45500207AB8 /* LocalStorageManager.swift in Sources */,
 				1756AE8124CB844500FD7257 /* View+Keyboard.swift in Sources */,
 				17C42E652509237800072984 /* PostListFilteredView.swift in Sources */,
 				170DFA34251BBC44001D82A0 /* PostEditorModel.swift in Sources */,
 				17120DAC24E1B99F002B9F6C /* AccountLoginView.swift in Sources */,
 				17480CA5251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */,
 				17AD0A6425489E900057D763 /* PostBodyTextView.swift in Sources */,
 				17AD0A5E25489E810057D763 /* PostTitleTextView.swift in Sources */,
 				17120DA924E1B2F5002B9F6C /* AccountLogoutView.swift in Sources */,
 				171BFDFA24D4AF8300888236 /* CollectionListView.swift in Sources */,
 				1756DBB324FECDBB00207AB8 /* PostEditorStatusToolbarView.swift in Sources */,
 				17120DB224E1E19C002B9F6C /* SettingsHeaderView.swift in Sources */,
 				1756DBB724FED3A400207AB8 /* LocalStorageModel.xcdatamodeld in Sources */,
 				17B996DA2502D23E0017B536 /* WFAPost+CoreDataProperties.swift in Sources */,
 				1756AE7724CB2EDD00FD7257 /* PostEditorView.swift in Sources */,
 				17DF32D524C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */,
 				17D435E824E3128F0036B539 /* PreferencesModel.swift in Sources */,
 				1765F62A24E18EA200C9EBF0 /* SidebarView.swift in Sources */,
 				1756AE7A24CB65DF00FD7257 /* PostListView.swift in Sources */,
 				17B996D82502D23E0017B536 /* WFAPost+CoreDataClass.swift in Sources */,
 				1756DC0124FEE18400207AB8 /* WFACollection+CoreDataClass.swift in Sources */,
 				17DF32AA24C87D3500BCE2E3 /* WriteFreely_MultiPlatformApp.swift in Sources */,
 				17120DA724E19D11002B9F6C /* SettingsView.swift in Sources */,
 				1756DC0324FEE18400207AB8 /* WFACollection+CoreDataProperties.swift in Sources */,
 				17120DA224E1985C002B9F6C /* AccountModel.swift in Sources */,
 				17120DA324E19A42002B9F6C /* PreferencesView.swift in Sources */,
 				1756AE6E24CB255B00FD7257 /* PostListModel.swift in Sources */,
 				173E19E3254329CC00440F0F /* PostTextEditingView.swift in Sources */,
 				174D313224EC2831006CA9EE /* WriteFreelyModel.swift in Sources */,
 				17C42E70250AA12300072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */,
 				17120DA124E19839002B9F6C /* AccountView.swift in Sources */,
 				1756AE7424CB26FA00FD7257 /* PostCellView.swift in Sources */,
 				17681E412519410E00D394AE /* UINavigationController+Appearance.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF328C24C87D3500BCE2E3 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 				17DF32AD24C87D3500BCE2E3 /* ContentView.swift in Sources */,
 				1765F62B24E18EA200C9EBF0 /* SidebarView.swift in Sources */,
 				1756DBBB24FED45500207AB8 /* LocalStorageManager.swift in Sources */,
+				17A4FEED25927E730037E96B /* AppDelegate.swift in Sources */,
 				174D313324EC2831006CA9EE /* WriteFreelyModel.swift in Sources */,
 				17D435E924E3128F0036B539 /* PreferencesModel.swift in Sources */,
 				17120DAA24E1B2F5002B9F6C /* AccountLogoutView.swift in Sources */,
 				17DF32D624C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */,
+				172C492E2593981900E20ADF /* MacUpdatesView.swift in Sources */,
 				17479F152583D8E40072B7FB /* PostEditorSharingPicker.swift in Sources */,
 				17480CA6251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */,
 				17C42E662509237800072984 /* PostListFilteredView.swift in Sources */,
 				17120DAD24E1B99F002B9F6C /* AccountLoginView.swift in Sources */,
 				17466626256C0D0600629997 /* MacEditorTextView.swift in Sources */,
 				17E5DF8A2543610700DCDC9B /* PostTextEditingView.swift in Sources */,
 				17C42E71250AAFD500072984 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */,
 				1756AE7B24CB65DF00FD7257 /* PostListView.swift in Sources */,
 				1753F6AC24E431CC00309365 /* MacPreferencesView.swift in Sources */,
 				1756DC0424FEE18400207AB8 /* WFACollection+CoreDataProperties.swift in Sources */,
 				17B996DB2502D23E0017B536 /* WFAPost+CoreDataProperties.swift in Sources */,
 				17BC618A25715318003363CA /* ActivePostToolbarView.swift in Sources */,
 				171BFDFB24D4AF8300888236 /* CollectionListView.swift in Sources */,
 				17A67CAF251A5DD7002F163D /* PostEditorView.swift in Sources */,
 				17DF32AB24C87D3500BCE2E3 /* WriteFreely_MultiPlatformApp.swift in Sources */,
 				17A5388C24DDC83F00DEFF9A /* AccountModel.swift in Sources */,
 				17B996D92502D23E0017B536 /* WFAPost+CoreDataClass.swift in Sources */,
 				1756DBB824FED3A400207AB8 /* LocalStorageModel.xcdatamodeld in Sources */,
 				17A5389324DDED0000DEFF9A /* PreferencesView.swift in Sources */,
 				1756AE6F24CB255B00FD7257 /* PostListModel.swift in Sources */,
 				1756DC0224FEE18400207AB8 /* WFACollection+CoreDataClass.swift in Sources */,
 				1756DBB424FECDBB00207AB8 /* PostEditorStatusToolbarView.swift in Sources */,
 				17A5388F24DDEC7400DEFF9A /* AccountView.swift in Sources */,
 				1780F6EF25895EDB00FE45FF /* PostCommands.swift in Sources */,
 				170DFA35251BBC44001D82A0 /* PostEditorModel.swift in Sources */,
 				1756AE7524CB26FA00FD7257 /* PostCellView.swift in Sources */,
 				17A5388824DDA31F00DEFF9A /* MacAccountView.swift in Sources */,
 				17C42E632507D8E600072984 /* PostStatus.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF329424C87D3500BCE2E3 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 				17DF329D24C87D3500BCE2E3 /* Tests_iOS.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		17DF329F24C87D3500BCE2E3 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 				17DF32A824C87D3500BCE2E3 /* Tests_macOS.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
 		17DF329A24C87D3500BCE2E3 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 17DF328724C87D3500BCE2E3 /* WriteFreely-MultiPlatform (iOS) */;
 			targetProxy = 17DF329924C87D3500BCE2E3 /* PBXContainerItemProxy */;
 		};
 		17DF32A524C87D3500BCE2E3 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 17DF328F24C87D3500BCE2E3 /* WriteFreely-MultiPlatform (macOS) */;
 			targetProxy = 17DF32A424C87D3500BCE2E3 /* PBXContainerItemProxy */;
 		};
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
 		17DF32B024C87D3500BCE2E3 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
 				CLANG_CXX_LIBRARY = "libc++";
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_ENABLE_OBJC_WEAK = YES;
 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_COMMA = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 				CLANG_WARN_STRICT_PROTOTYPES = YES;
 				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				GCC_DYNAMIC_NO_PIC = NO;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = (
 					"DEBUG=1",
 					"$(inherited)",
 				);
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 			};
 			name = Debug;
 		};
 		17DF32B124C87D3500BCE2E3 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
 				CLANG_CXX_LIBRARY = "libc++";
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_ENABLE_OBJC_WEAK = YES;
 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_COMMA = YES;
 				CLANG_WARN_CONSTANT_CONVERSION = YES;
 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 				CLANG_WARN_STRICT_PROTOTYPES = YES;
 				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				ENABLE_NS_ASSERTIONS = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				MTL_FAST_MATH = YES;
 				SWIFT_COMPILATION_MODE = wholemodule;
 				SWIFT_OPTIMIZATION_LEVEL = "-O";
 			};
 			name = Release;
 		};
 		17DF32B324C87D3500BCE2E3 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 438;
 				DEVELOPMENT_TEAM = TPPAB4YBA6;
 				ENABLE_PREVIEWS = YES;
 				INFOPLIST_FILE = iOS/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
 				MARKETING_VERSION = 1.0.1;
 				PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
 				PRODUCT_NAME = "WriteFreely-MultiPlatform";
 				SDKROOT = iphoneos;
 				SWIFT_VERSION = 5.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
 			};
 			name = Debug;
 		};
 		17DF32B424C87D3500BCE2E3 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 438;
 				DEVELOPMENT_TEAM = TPPAB4YBA6;
 				ENABLE_PREVIEWS = YES;
 				INFOPLIST_FILE = iOS/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
 				MARKETING_VERSION = 1.0.1;
 				PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
 				PRODUCT_NAME = "WriteFreely-MultiPlatform";
 				SDKROOT = iphoneos;
 				SWIFT_VERSION = 5.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				VALIDATE_PRODUCT = YES;
 			};
 			name = Release;
 		};
 		17DF32B624C87D3500BCE2E3 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements;
 				CODE_SIGN_STYLE = Automatic;
 				COMBINE_HIDPI_IMAGES = YES;
 				CURRENT_PROJECT_VERSION = 514;
 				DEVELOPMENT_TEAM = TPPAB4YBA6;
 				ENABLE_HARDENED_RUNTIME = YES;
 				ENABLE_PREVIEWS = YES;
 				INFOPLIST_FILE = macOS/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/../Frameworks",
 				);
 				MACOSX_DEPLOYMENT_TARGET = 11.0;
 				MARKETING_VERSION = 1.0b1;
 				PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
 				PRODUCT_NAME = "WriteFreely for Mac";
 				SDKROOT = macosx;
 				SWIFT_VERSION = 5.0;
 			};
 			name = Debug;
 		};
 		17DF32B724C87D3500BCE2E3 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements;
 				CODE_SIGN_STYLE = Automatic;
 				COMBINE_HIDPI_IMAGES = YES;
 				CURRENT_PROJECT_VERSION = 514;
 				DEVELOPMENT_TEAM = TPPAB4YBA6;
 				ENABLE_HARDENED_RUNTIME = YES;
 				ENABLE_PREVIEWS = YES;
 				INFOPLIST_FILE = macOS/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/../Frameworks",
 				);
 				MACOSX_DEPLOYMENT_TARGET = 11.0;
 				MARKETING_VERSION = 1.0b1;
 				PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.WriteFreely-MultiPlatform";
 				PRODUCT_NAME = "WriteFreely for Mac";
 				SDKROOT = macosx;
 				SWIFT_VERSION = 5.0;
 			};
 			name = Release;
 		};
 		17DF32B924C87D3500BCE2E3 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				CODE_SIGN_STYLE = Automatic;
 				DEVELOPMENT_TEAM = TPPAB4YBA6;
 				INFOPLIST_FILE = "Tests iOS/Info.plist";
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@loader_path/Frameworks",
 				);
 				PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.Tests-iOS";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = iphoneos;
 				SWIFT_VERSION = 5.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				TEST_TARGET_NAME = "WriteFreely-MultiPlatform (iOS)";
 			};
 			name = Debug;
 		};
 		17DF32BA24C87D3500BCE2E3 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				CODE_SIGN_STYLE = Automatic;
 				DEVELOPMENT_TEAM = TPPAB4YBA6;
 				INFOPLIST_FILE = "Tests iOS/Info.plist";
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 					"@loader_path/Frameworks",
 				);
 				PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.Tests-iOS";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = iphoneos;
 				SWIFT_VERSION = 5.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				TEST_TARGET_NAME = "WriteFreely-MultiPlatform (iOS)";
 				VALIDATE_PRODUCT = YES;
 			};
 			name = Release;
 		};
 		17DF32BC24C87D3500BCE2E3 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				CODE_SIGN_STYLE = Automatic;
 				COMBINE_HIDPI_IMAGES = YES;
 				DEVELOPMENT_TEAM = TPPAB4YBA6;
 				INFOPLIST_FILE = "Tests macOS/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/../Frameworks",
 					"@loader_path/../Frameworks",
 				);
 				MACOSX_DEPLOYMENT_TARGET = 10.15;
 				PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.Tests-macOS";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = macosx;
 				SWIFT_VERSION = 5.0;
 				TEST_TARGET_NAME = "WriteFreely-MultiPlatform (macOS)";
 			};
 			name = Debug;
 		};
 		17DF32BD24C87D3500BCE2E3 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
 				CODE_SIGN_STYLE = Automatic;
 				COMBINE_HIDPI_IMAGES = YES;
 				DEVELOPMENT_TEAM = TPPAB4YBA6;
 				INFOPLIST_FILE = "Tests macOS/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/../Frameworks",
 					"@loader_path/../Frameworks",
 				);
 				MACOSX_DEPLOYMENT_TARGET = 10.15;
 				PRODUCT_BUNDLE_IDENTIFIER = "com.abunchtell.Tests-macOS";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = macosx;
 				SWIFT_VERSION = 5.0;
 				TEST_TARGET_NAME = "WriteFreely-MultiPlatform (macOS)";
 			};
 			name = Release;
 		};
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
 		17DF327F24C87D3300BCE2E3 /* Build configuration list for PBXProject "WriteFreely-MultiPlatform" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				17DF32B024C87D3500BCE2E3 /* Debug */,
 				17DF32B124C87D3500BCE2E3 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
 		17DF32B224C87D3500BCE2E3 /* Build configuration list for PBXNativeTarget "WriteFreely-MultiPlatform (iOS)" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				17DF32B324C87D3500BCE2E3 /* Debug */,
 				17DF32B424C87D3500BCE2E3 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
 		17DF32B524C87D3500BCE2E3 /* Build configuration list for PBXNativeTarget "WriteFreely-MultiPlatform (macOS)" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				17DF32B624C87D3500BCE2E3 /* Debug */,
 				17DF32B724C87D3500BCE2E3 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
 		17DF32B824C87D3500BCE2E3 /* Build configuration list for PBXNativeTarget "Tests iOS" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				17DF32B924C87D3500BCE2E3 /* Debug */,
 				17DF32BA24C87D3500BCE2E3 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
 		17DF32BB24C87D3500BCE2E3 /* Build configuration list for PBXNativeTarget "Tests macOS" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				17DF32BC24C87D3500BCE2E3 /* Debug */,
 				17DF32BD24C87D3500BCE2E3 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
 /* End XCConfigurationList section */
 
 /* Begin XCRemoteSwiftPackageReference section */
+		17A4FED825924AF70037E96B /* XCRemoteSwiftPackageReference "Sparkle" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/writefreely/Sparkle";
+			requirement = {
+				branch = master;
+				kind = branch;
+			};
+		};
 		17DF32BE24C87D7B00BCE2E3 /* XCRemoteSwiftPackageReference "writefreely-swift" */ = {
 			isa = XCRemoteSwiftPackageReference;
 			repositoryURL = "git@github.com:writeas/writefreely-swift.git";
 			requirement = {
 				kind = upToNextMajorVersion;
 				minimumVersion = 0.3.0;
 			};
 		};
 /* End XCRemoteSwiftPackageReference section */
 
 /* Begin XCSwiftPackageProductDependency section */
+		17A4FED925924AF70037E96B /* Sparkle */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = 17A4FED825924AF70037E96B /* XCRemoteSwiftPackageReference "Sparkle" */;
+			productName = Sparkle;
+		};
 		17DF32BF24C87D7B00BCE2E3 /* WriteFreely */ = {
 			isa = XCSwiftPackageProductDependency;
 			package = 17DF32BE24C87D7B00BCE2E3 /* XCRemoteSwiftPackageReference "writefreely-swift" */;
 			productName = WriteFreely;
 		};
 		17DF32C224C87D8D00BCE2E3 /* WriteFreely */ = {
 			isa = XCSwiftPackageProductDependency;
 			package = 17DF32BE24C87D7B00BCE2E3 /* XCRemoteSwiftPackageReference "writefreely-swift" */;
 			productName = WriteFreely;
 		};
 /* End XCSwiftPackageProductDependency section */
 
 /* Begin XCVersionGroup section */
 		1756DBB524FED3A400207AB8 /* LocalStorageModel.xcdatamodeld */ = {
 			isa = XCVersionGroup;
 			children = (
 				1756DBB624FED3A400207AB8 /* LocalStorageModel.xcdatamodel */,
 			);
 			currentVersion = 1756DBB624FED3A400207AB8 /* LocalStorageModel.xcdatamodel */;
 			path = LocalStorageModel.xcdatamodeld;
 			sourceTree = "";
 			versionGroupType = wrapper.xcdatamodel;
 		};
 /* End XCVersionGroup section */
 	};
 	rootObject = 17DF327C24C87D3300BCE2E3 /* Project object */;
 }
diff --git a/macOS/AppDelegate.swift b/macOS/AppDelegate.swift
new file mode 100644
index 0000000..f23d06e
--- /dev/null
+++ b/macOS/AppDelegate.swift
@@ -0,0 +1,24 @@
+import Cocoa
+import Sparkle
+
+class AppDelegate: NSObject, NSApplicationDelegate {
+    func applicationWillFinishLaunching(_ notification: Notification) {
+        // Check UserDefaults for values; if the key doesn't exist (e.g., if MacUpdatesView hasn't ever been shown),
+        // bool(forKey:) returns false, so set SUUpdater.shared() appropriately.
+        let automaticallyChecksForUpdates = UserDefaults.standard.bool(forKey: "automaticallyChecksForUpdates")
+        let subscribeToBetaUpdates = UserDefaults.standard.bool(forKey: "subscribeToBetaUpdates")
+
+        // Set Sparkle properties.
+        SUUpdater.shared()?.automaticallyChecksForUpdates = automaticallyChecksForUpdates
+        if subscribeToBetaUpdates {
+            SUUpdater.shared()?.feedURL = URL(string: AppcastFeedUrl.beta.rawValue)
+        } else {
+            SUUpdater.shared()?.feedURL = URL(string: AppcastFeedUrl.release.rawValue)
+        }
+
+        // If enabled, check for updates.
+        if automaticallyChecksForUpdates {
+            SUUpdater.shared()?.checkForUpdates(self)
+        }
+    }
+}
diff --git a/macOS/Credits.rtf b/macOS/Credits.rtf
index 17b79ca..b8dad72 100644
--- a/macOS/Credits.rtf
+++ b/macOS/Credits.rtf
@@ -1,22 +1,23 @@
 {\rtf1\ansi\ansicpg1252\cocoartf2578
 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 SFProDisplay-Regular;}
 {\colortbl;\red255\green255\blue255;}
 {\*\expandedcolortbl;;}
 {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}}
 {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
 \margl1440\margr1440\vieww9000\viewh8400\viewkind0
 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
 
-\f0\fs26 \cf0 This application makes use of the following open-source projects:\
+\f0\fs26 \cf0 WriteFreely for Mac makes use of the following open-source projects:\
 \
 \pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0
-\ls1\ilvl0\cf0 {\listtext	\uc0\u8226 	}Lora typeface\
-{\listtext	\uc0\u8226 	}Open Sans typeface\
-{\listtext	\uc0\u8226 	}Hack typeface\
+\ls1\ilvl0\cf0 {\listtext	\uc0\u8226 	}Lora ({\field{\*\fldinst{HYPERLINK "https://github.com/cyrealtype/Lora-Cyrillic"}}{\fldrslt typeface}})\
+{\listtext	\uc0\u8226 	}Open Sans ({\field{\*\fldinst{HYPERLINK "https://fonts.google.com/specimen/Open+Sans"}}{\fldrslt typeface}})\
+{\listtext	\uc0\u8226 	}Hack ({\field{\*\fldinst{HYPERLINK "https://sourcefoundry.org/hack/"}}{\fldrslt typeface}})\
+{\listtext	\uc0\u8226 	}Sparkle ({\field{\*\fldinst{HYPERLINK "https://sparkle-project.org"}}{\fldrslt framework}})\
 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
 \cf0 \
 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
 {\field{\*\fldinst{HYPERLINK "https://github.com/writeas/writefreely-swiftui-multiplatform/tree/main/Shared/Resources/Licenses"}}{\fldrslt \cf0 View the licenses}}\
 \
 The post editor is based on Thiago Holanda's {\field{\*\fldinst{HYPERLINK "https://gist.github.com/unnamedd/6e8c3fbc806b8deb60fa65d6b9affab0"}}{\fldrslt MacEditorTextView}} gist.\
 }
\ No newline at end of file
diff --git a/macOS/Info.plist b/macOS/Info.plist
index 0762008..5b2a81e 100644
--- a/macOS/Info.plist
+++ b/macOS/Info.plist
@@ -1,32 +1,36 @@
 
 
 
 
 	ATSApplicationFontsPath
 	.
 	CFBundleDevelopmentRegion
 	$(DEVELOPMENT_LANGUAGE)
 	CFBundleDisplayName
 	WriteFreely
 	CFBundleExecutable
 	$(EXECUTABLE_NAME)
 	CFBundleIconFile
 	
 	CFBundleIdentifier
 	$(PRODUCT_BUNDLE_IDENTIFIER)
 	CFBundleInfoDictionaryVersion
 	6.0
 	CFBundleName
 	WriteFreely
 	CFBundlePackageType
 	$(PRODUCT_BUNDLE_PACKAGE_TYPE)
 	CFBundleShortVersionString
 	$(MARKETING_VERSION)
 	CFBundleVersion
 	$(CURRENT_PROJECT_VERSION)
 	LSApplicationCategoryType
 	public.app-category.social-networking
 	LSMinimumSystemVersion
 	$(MACOSX_DEPLOYMENT_TARGET)
+	SUFeedURL
+	https://writefreely-files.s3.amazonaws.com/apps/mac/appcast.xml
+	SUPublicEDKey
+	xLenuurDaQb2/dj2ScylLmJx0gSnBmacUsOAgUjErUc=
 
 
diff --git a/macOS/Settings/MacAccountView.swift b/macOS/Settings/MacAccountView.swift
index e51dfd7..f0d4c30 100644
--- a/macOS/Settings/MacAccountView.swift
+++ b/macOS/Settings/MacAccountView.swift
@@ -1,20 +1,18 @@
 import SwiftUI
 
 struct MacAccountView: View {
     @EnvironmentObject var model: WriteFreelyModel
 
     var body: some View {
             Form {
-                Section(header: Text("Login Details")) {
                     AccountView()
-                }
             }
     }
 }
 
 struct MacAccountView_Previews: PreviewProvider {
     static var previews: some View {
         MacAccountView()
             .environmentObject(WriteFreelyModel())
     }
 }
diff --git a/macOS/Settings/MacUpdatesView.swift b/macOS/Settings/MacUpdatesView.swift
new file mode 100644
index 0000000..45f682a
--- /dev/null
+++ b/macOS/Settings/MacUpdatesView.swift
@@ -0,0 +1,93 @@
+import SwiftUI
+import Sparkle
+
+enum AppcastFeedUrl: String {
+    case release = "https://writefreely-files.s3.amazonaws.com/apps/mac/appcast.xml"
+    case beta = "https://writefreely-files.s3.amazonaws.com/apps/mac/appcast-beta.xml"
+}
+
+struct MacUpdatesView: View {
+    @AppStorage("automaticallyChecksForUpdates") var automaticallyChecksForUpdates: Bool = false
+    @AppStorage("subscribeToBetaUpdates") var subscribeToBetaUpdates: Bool = false
+    @State private var lastUpdateCheck: Date?
+
+    private let betaWarningString = """
+To get brand new features before each official release, choose "Test versions." Note that test versions may have bugs \
+that can cause crashes and data loss.
+"""
+
+    static let lastUpdateFormatter: DateFormatter = {
+        let formatter = DateFormatter()
+        formatter.dateStyle = .short
+        formatter.timeStyle = .short
+        formatter.doesRelativeDateFormatting = true
+        return formatter
+    }()
+
+    var body: some View {
+        VStack(spacing: 24) {
+            Toggle(isOn: $automaticallyChecksForUpdates, label: {
+                Text("Check for updates automatically")
+            })
+
+            VStack {
+                Button(action: {
+                    SUUpdater.shared()?.checkForUpdates(self)
+                    DispatchQueue.main.async {
+                        lastUpdateCheck = SUUpdater.shared()?.lastUpdateCheckDate
+                    }
+                }, label: {
+                    Text("Check For Updates")
+                })
+
+                HStack {
+                    Text("Last checked:")
+                        .font(.caption)
+                    if let lastUpdateCheck = lastUpdateCheck {
+                        Text(lastUpdateCheck, formatter: Self.lastUpdateFormatter)
+                            .font(.caption)
+                    } else {
+                        Text("Never")
+                            .font(.caption)
+                    }
+                }
+            }
+
+            VStack(spacing: 16) {
+                HStack(alignment: .top) {
+                    Text("Download:")
+                    Picker(selection: $subscribeToBetaUpdates, label: Text("Download:"), content: {
+                        Text("Release versions").tag(false)
+                        Text("Test versions").tag(true)
+                    })
+                    .pickerStyle(RadioGroupPickerStyle())
+                    .labelsHidden()
+                }
+
+                Text(betaWarningString)
+                    .frame(width: 350)
+                    .foregroundColor(.secondary)
+            }
+        }
+        .padding()
+        .onAppear {
+            lastUpdateCheck = SUUpdater.shared()?.lastUpdateCheckDate
+        }
+        .onChange(of: automaticallyChecksForUpdates) { value in
+            SUUpdater.shared()?.automaticallyChecksForUpdates = value
+        }
+        .onChange(of: subscribeToBetaUpdates) { value in
+            if value {
+                SUUpdater.shared()?.feedURL = URL(string: AppcastFeedUrl.beta.rawValue)
+            } else {
+                SUUpdater.shared()?.feedURL = URL(string: AppcastFeedUrl.release.rawValue)
+            }
+        }
+    }
+}
+
+struct MacUpdatesView_Previews: PreviewProvider {
+    static var previews: some View {
+        MacUpdatesView()
+    }
+}
diff --git a/macOS/macOS.entitlements b/macOS/macOS.entitlements
index 40b639e..0c67376 100644
--- a/macOS/macOS.entitlements
+++ b/macOS/macOS.entitlements
@@ -1,14 +1,5 @@
 
 
 
-
-	com.apple.security.app-sandbox
-	
-	com.apple.security.files.user-selected.read-only
-	
-	com.apple.security.network.client
-	
-	com.apple.security.network.server
-	
-
+