mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Merge pull request #163 from writeas/integrate-sparkle-via-spm
Integrate sparkle via spm
This commit is contained in:
commit
34dfc1d7e1
61
Shared/Resources/Licenses/Sparkle-License.txt
Normal file
61
Shared/Resources/Licenses/Sparkle-License.txt
Normal file
@ -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 <http://www.daemonology.net/bsdiff/>:
|
||||
Copyright (c) 2003-2005 Colin Percival.
|
||||
|
||||
sais.c and sais.c, from sais-lite (2010/08/07) <https://sites.google.com/site/yuta256/sais>:
|
||||
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.
|
@ -1,5 +1,9 @@
|
||||
import SwiftUI
|
||||
|
||||
#if os(macOS)
|
||||
import Sparkle
|
||||
#endif
|
||||
|
||||
@main
|
||||
struct CheckForDebugModifier {
|
||||
static func main() {
|
||||
@ -20,6 +24,8 @@ 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
|
||||
|
||||
@ -38,6 +44,13 @@ struct WriteFreely_MultiPlatformApp: App {
|
||||
// .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()
|
||||
@ -85,8 +98,14 @@ struct WriteFreely_MultiPlatformApp: App {
|
||||
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.
|
||||
}
|
||||
|
66
Technotes/MacSoftwareUpdater.md
Normal file
66
Technotes/MacSoftwareUpdater.md
Normal file
@ -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 <source_path_to_app> <zip_destination>
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
<!--references-->
|
||||
[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/
|
@ -20,6 +20,7 @@
|
||||
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 */; };
|
||||
@ -51,6 +52,8 @@
|
||||
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 */; };
|
||||
@ -125,6 +128,7 @@
|
||||
17120DAB24E1B99F002B9F6C /* AccountLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountLoginView.swift; sourceTree = "<group>"; };
|
||||
17120DB124E1E19C002B9F6C /* SettingsHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeaderView.swift; sourceTree = "<group>"; };
|
||||
171BFDF924D4AF8300888236 /* CollectionListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionListView.swift; sourceTree = "<group>"; };
|
||||
172C492D2593981900E20ADF /* MacUpdatesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacUpdatesView.swift; sourceTree = "<group>"; };
|
||||
173E19D0254318F600440F0F /* RemoteChangePromptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteChangePromptView.swift; sourceTree = "<group>"; };
|
||||
173E19E2254329CC00440F0F /* PostTextEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTextEditingView.swift; sourceTree = "<group>"; };
|
||||
17466625256C0D0600629997 /* MacEditorTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacEditorTextView.swift; sourceTree = "<group>"; };
|
||||
@ -145,6 +149,8 @@
|
||||
1765F62924E18EA200C9EBF0 /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = "<group>"; };
|
||||
17681E402519410E00D394AE /* UINavigationController+Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Appearance.swift"; sourceTree = "<group>"; };
|
||||
1780F6EE25895EDB00FE45FF /* PostCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostCommands.swift; sourceTree = "<group>"; };
|
||||
17A4FEDF25924E810037E96B /* MacSoftwareUpdater.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = MacSoftwareUpdater.md; sourceTree = "<group>"; };
|
||||
17A4FEEC25927E730037E96B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
17A5388724DDA31F00DEFF9A /* MacAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacAccountView.swift; sourceTree = "<group>"; };
|
||||
17A5388B24DDC83F00DEFF9A /* AccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountModel.swift; sourceTree = "<group>"; };
|
||||
17A5388D24DDEC7400DEFF9A /* AccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountView.swift; sourceTree = "<group>"; };
|
||||
@ -154,6 +160,7 @@
|
||||
17AD0A6325489E900057D763 /* PostBodyTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostBodyTextView.swift; sourceTree = "<group>"; };
|
||||
17B3E964250FAA9000EE9748 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
17B5103A2515448D00E9631F /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
|
||||
17B68D4F25A4FED2005ED37C /* Sparkle-License.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Sparkle-License.txt"; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
@ -204,6 +211,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
17DF32C324C87D8D00BCE2E3 /* WriteFreely in Frameworks */,
|
||||
17A4FEDA25924AF70037E96B /* Sparkle in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -228,6 +236,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1709ADDF251B9A110053AF79 /* EditorLaunchingPolicy.md */,
|
||||
17A4FEDF25924E810037E96B /* MacSoftwareUpdater.md */,
|
||||
);
|
||||
path = Technotes;
|
||||
sourceTree = "<group>";
|
||||
@ -296,6 +305,7 @@
|
||||
children = (
|
||||
17A5388724DDA31F00DEFF9A /* MacAccountView.swift */,
|
||||
1753F6AB24E431CC00309365 /* MacPreferencesView.swift */,
|
||||
172C492D2593981900E20ADF /* MacUpdatesView.swift */,
|
||||
);
|
||||
path = Settings;
|
||||
sourceTree = "<group>";
|
||||
@ -409,6 +419,7 @@
|
||||
children = (
|
||||
17DF329224C87D3500BCE2E3 /* Info.plist */,
|
||||
17DF329324C87D3500BCE2E3 /* macOS.entitlements */,
|
||||
17A4FEEC25927E730037E96B /* AppDelegate.swift */,
|
||||
17BC617725715042003363CA /* Navigation */,
|
||||
17A67CAC251A5D8D002F163D /* PostEditor */,
|
||||
17A5388924DDA50500DEFF9A /* Settings */,
|
||||
@ -485,6 +496,7 @@
|
||||
17DFDE83251D309400A25F31 /* Licenses */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17B68D4F25A4FED2005ED37C /* Sparkle-License.txt */,
|
||||
17DFDE84251D309400A25F31 /* Hack-License.txt */,
|
||||
17DFDE85251D309400A25F31 /* Lora-Cyrillic-OFL.txt */,
|
||||
17DFDE86251D309400A25F31 /* OpenSans-License.txt */,
|
||||
@ -532,6 +544,7 @@
|
||||
name = "WriteFreely-MultiPlatform (macOS)";
|
||||
packageProductDependencies = (
|
||||
17DF32C224C87D8D00BCE2E3 /* WriteFreely */,
|
||||
17A4FED925924AF70037E96B /* Sparkle */,
|
||||
);
|
||||
productName = "WriteFreely-MultiPlatform (macOS)";
|
||||
productReference = 17DF329024C87D3500BCE2E3 /* WriteFreely for Mac.app */;
|
||||
@ -609,6 +622,7 @@
|
||||
mainGroup = 17DF327B24C87D3300BCE2E3;
|
||||
packageReferences = (
|
||||
17DF32BE24C87D7B00BCE2E3 /* XCRemoteSwiftPackageReference "writefreely-swift" */,
|
||||
17A4FED825924AF70037E96B /* XCRemoteSwiftPackageReference "Sparkle" */,
|
||||
);
|
||||
productRefGroup = 17DF328924C87D3500BCE2E3 /* Products */;
|
||||
projectDirPath = "";
|
||||
@ -757,10 +771,12 @@
|
||||
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 */,
|
||||
@ -1176,6 +1192,14 @@
|
||||
/* 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";
|
||||
@ -1187,6 +1211,11 @@
|
||||
/* 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" */;
|
||||
|
24
macOS/AppDelegate.swift
Normal file
24
macOS/AppDelegate.swift
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -7,12 +7,13 @@
|
||||
\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
|
||||
|
@ -28,5 +28,9 @@
|
||||
<string>public.app-category.social-networking</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>SUFeedURL</key>
|
||||
<string>https://writefreely-files.s3.amazonaws.com/apps/mac/appcast.xml</string>
|
||||
<key>SUPublicEDKey</key>
|
||||
<string>xLenuurDaQb2/dj2ScylLmJx0gSnBmacUsOAgUjErUc=</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -5,9 +5,7 @@ struct MacAccountView: View {
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
Section(header: Text("Login Details")) {
|
||||
AccountView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
93
macOS/Settings/MacUpdatesView.swift
Normal file
93
macOS/Settings/MacUpdatesView.swift
Normal file
@ -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()
|
||||
}
|
||||
}
|
@ -1,14 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict/>
|
||||
</plist>
|
||||
|
Loading…
Reference in New Issue
Block a user