diff --git a/MAS_SUBMISSION_GUIDE.md b/MAS_SUBMISSION_GUIDE.md
new file mode 100644
index 0000000..269272d
--- /dev/null
+++ b/MAS_SUBMISSION_GUIDE.md
@@ -0,0 +1,110 @@
+# Mac App Store Submission Guide
+
+## Prerequisites
+
+- Apple Developer account with App Store Connect access
+- Xcode with "Apple Distribution" signing certificate installed
+- Mac App Store provisioning profile for `com.macscp.macSCP`
+
+## Build Configuration
+
+### MAS Build Flag
+
+This project uses a `MAS_BUILD` Swift compiler flag to conditionally exclude Sparkle (third-party update framework), which Apple does not allow on the App Store.
+
+To build for the Mac App Store:
+
+1. In Xcode, go to **Build Settings** → **Swift Compiler - Custom Flags** → **Active Compilation Conditions**
+2. Add `MAS_BUILD` to the Release configuration
+3. Alternatively, pass it via xcodebuild:
+
+```bash
+xcodebuild archive \
+ -project macSCP.xcodeproj \
+ -scheme macSCP \
+ -archivePath build/macSCP-MAS.xcarchive \
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS='$(inherited) MAS_BUILD' \
+ CODE_SIGN_IDENTITY="Apple Distribution" \
+ CODE_SIGN_STYLE=Manual \
+ PROVISIONING_PROFILE_SPECIFIER="macSCP App Store"
+```
+
+### MAS Entitlements
+
+Use `macSCP/macSCP_MAS.entitlements` for the App Store build. This file mirrors the standard entitlements but is suitable for MAS distribution.
+
+When exporting the archive:
+
+```bash
+xcodebuild -exportArchive \
+ -archivePath build/macSCP-MAS.xcarchive \
+ -exportPath build/MAS \
+ -exportOptionsPlist ExportOptions-MAS.plist
+```
+
+### ExportOptions-MAS.plist (create this)
+
+```xml
+
+
+
+
+ method
+ app-store
+ teamID
+ NW7K6UFA6P
+ uploadSymbols
+
+ signingStyle
+ manual
+ signingCertificate
+ Apple Distribution
+ provisioningProfiles
+
+ com.macscp.macSCP
+ macSCP App Store
+
+
+
+```
+
+## App Store Connect Setup
+
+1. **Create the app** in App Store Connect with bundle ID `com.macscp.macSCP`
+2. **App Information**:
+ - Name: macSCP
+ - Subtitle: SFTP, S3 & SSH for Mac
+ - Category: Developer Tools
+ - Secondary Category: Utilities
+3. **Description**:
+ > macSCP is a native macOS client for managing remote servers via SFTP, Amazon S3, and SSH terminal — all in one app built with SwiftUI.
+ >
+ > Features:
+ > • SFTP file browser with drag-and-drop transfers
+ > • Amazon S3 bucket management
+ > • Built-in SSH terminal
+ > • Secure credential storage in Keychain
+ > • Multiple simultaneous connections
+ > • Dark mode support
+4. **Keywords**: sftp, s3, ssh, terminal, file transfer, remote, server, ftp, macos, developer
+5. **Screenshots**: Required sizes — 1280x800 and 1440x900 (or retina equivalents)
+6. **Privacy Policy URL**: Required — add to macscp.co
+7. **Support URL**: https://github.com/macnev2013/macSCP/issues
+8. **Marketing URL**: https://www.macscp.co
+
+## Upload & Submit
+
+1. Archive in Xcode (Product → Archive) with MAS build settings
+2. Upload via Xcode Organizer or `xcrun altool --upload-app`
+3. In App Store Connect, select the build and submit for review
+
+## Review Notes
+
+> macSCP requires network access (outgoing and incoming) to connect to SFTP servers, Amazon S3 buckets, and SSH terminals. The app stores connection credentials securely in the macOS Keychain.
+>
+> To test: Add an SFTP connection using any publicly accessible SFTP server, or configure an S3 bucket with valid AWS credentials.
+
+## Timeline
+
+- App Store review typically takes 1-3 days
+- Submit by March 22 to be live for launch week (March 25+)
diff --git a/macSCP.xcodeproj/project.pbxproj b/macSCP.xcodeproj/project.pbxproj
index 1050081..d09d0bd 100644
--- a/macSCP.xcodeproj/project.pbxproj
+++ b/macSCP.xcodeproj/project.pbxproj
@@ -511,7 +511,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MARKETING_VERSION = 0.2.4;
+ MARKETING_VERSION = 0.2.7;
PRODUCT_BUNDLE_IDENTIFIER = com.macscp.macSCP;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
@@ -558,7 +558,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- MARKETING_VERSION = 0.2.4;
+ MARKETING_VERSION = 0.2.7;
PRODUCT_BUNDLE_IDENTIFIER = com.macscp.macSCP;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
diff --git a/macSCP/App/MacSCPApp.swift b/macSCP/App/MacSCPApp.swift
index 78abdaa..41274be 100644
--- a/macSCP/App/MacSCPApp.swift
+++ b/macSCP/App/MacSCPApp.swift
@@ -7,19 +7,24 @@
import SwiftUI
import SwiftData
+#if !MAS_BUILD
import Sparkle
+#endif
@main
struct MacSCPApp: App {
@StateObject private var container = DependencyContainer.shared
+ #if !MAS_BUILD
private let updaterController: SPUStandardUpdaterController
@StateObject private var checkForUpdatesViewModel: CheckForUpdatesViewModel
+ #endif
init() {
AnalyticsService.initialize()
AppLockManager.shared.lockIfNeeded()
+ #if !MAS_BUILD
let controller = SPUStandardUpdaterController(
startingUpdater: true,
updaterDelegate: nil,
@@ -29,6 +34,7 @@ struct MacSCPApp: App {
self._checkForUpdatesViewModel = StateObject(
wrappedValue: CheckForUpdatesViewModel(updater: controller.updater)
)
+ #endif
}
var body: some Scene {
@@ -94,9 +100,11 @@ struct MacSCPApp: App {
// MARK: - Commands
@CommandsBuilder
private var appCommands: some Commands {
+ #if !MAS_BUILD
CommandGroup(after: .appInfo) {
CheckForUpdatesView(viewModel: checkForUpdatesViewModel)
}
+ #endif
CommandGroup(replacing: .newItem) {
Button("New Connection") {
diff --git a/macSCP/Features/Settings/CheckForUpdatesView.swift b/macSCP/Features/Settings/CheckForUpdatesView.swift
index 7a7c192..7bb421a 100644
--- a/macSCP/Features/Settings/CheckForUpdatesView.swift
+++ b/macSCP/Features/Settings/CheckForUpdatesView.swift
@@ -3,6 +3,7 @@
// macSCP
//
+#if !MAS_BUILD
import SwiftUI
struct CheckForUpdatesView: View {
@@ -13,3 +14,4 @@ struct CheckForUpdatesView: View {
.disabled(!viewModel.canCheckForUpdates)
}
}
+#endif
diff --git a/macSCP/Features/Settings/CheckForUpdatesViewModel.swift b/macSCP/Features/Settings/CheckForUpdatesViewModel.swift
index 2bca11e..820c33b 100644
--- a/macSCP/Features/Settings/CheckForUpdatesViewModel.swift
+++ b/macSCP/Features/Settings/CheckForUpdatesViewModel.swift
@@ -3,6 +3,7 @@
// macSCP
//
+#if !MAS_BUILD
import Combine
import Foundation
import Sparkle
@@ -26,3 +27,4 @@ final class CheckForUpdatesViewModel: ObservableObject {
logInfo("Manual update check triggered", category: .app)
}
}
+#endif
diff --git a/macSCP/macSCP_MAS.entitlements b/macSCP/macSCP_MAS.entitlements
new file mode 100644
index 0000000..c55be86
--- /dev/null
+++ b/macSCP/macSCP_MAS.entitlements
@@ -0,0 +1,20 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.network.client
+
+ com.apple.security.network.server
+
+ com.apple.security.files.user-selected.read-write
+
+ com.apple.security.files.downloads.read-write
+
+ keychain-access-groups
+
+ $(AppIdentifierPrefix)com.macSCP.keychain
+
+
+