mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-10 23:33:29 +01:00
XCode project for app, moved app project to folder
This commit is contained in:
69
SideStoreApp/Sources/Shared/Extensions/Bundle+AltStore.swift
Normal file
69
SideStoreApp/Sources/Shared/Extensions/Bundle+AltStore.swift
Normal file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Bundle+AltStore.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Riley Testut on 5/30/19.
|
||||
// Copyright © 2019 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension Bundle {
|
||||
enum Info {
|
||||
public static let deviceID = "ALTDeviceID"
|
||||
public static let serverID = "ALTServerID"
|
||||
public static let certificateID = "ALTCertificateID"
|
||||
public static let appGroups = "ALTAppGroups"
|
||||
public static let altBundleID = "ALTBundleIdentifier"
|
||||
public static let orgbundleIdentifier = "com.SideStore"
|
||||
public static let appbundleIdentifier = orgbundleIdentifier + ".SideStore"
|
||||
public static let devicePairingString = "ALTPairingFile"
|
||||
public static let urlTypes = "CFBundleURLTypes"
|
||||
public static let exportedUTIs = "UTExportedTypeDeclarations"
|
||||
|
||||
public static let untetherURL = "ALTFugu14UntetherURL"
|
||||
public static let untetherRequired = "ALTFugu14UntetherRequired"
|
||||
public static let untetherMinimumiOSVersion = "ALTFugu14UntetherMinimumVersion"
|
||||
public static let untetherMaximumiOSVersion = "ALTFugu14UntetherMaximumVersion"
|
||||
}
|
||||
}
|
||||
|
||||
public extension Bundle {
|
||||
var infoPlistURL: URL {
|
||||
let infoPlistURL = bundleURL.appendingPathComponent("Info.plist")
|
||||
return infoPlistURL
|
||||
}
|
||||
|
||||
var provisioningProfileURL: URL {
|
||||
let provisioningProfileURL = bundleURL.appendingPathComponent("embedded.mobileprovision")
|
||||
return provisioningProfileURL
|
||||
}
|
||||
|
||||
var certificateURL: URL {
|
||||
let certificateURL = bundleURL.appendingPathComponent("ALTCertificate.p12")
|
||||
return certificateURL
|
||||
}
|
||||
|
||||
var altstorePlistURL: URL {
|
||||
let altstorePlistURL = bundleURL.appendingPathComponent("AltStore.plist")
|
||||
return altstorePlistURL
|
||||
}
|
||||
}
|
||||
|
||||
public extension Bundle {
|
||||
static var baseAltStoreAppGroupID = "group.com.SideStore.SideStore"
|
||||
|
||||
var appGroups: [String] {
|
||||
infoDictionary?[Bundle.Info.appGroups] as? [String] ?? []
|
||||
}
|
||||
|
||||
var altstoreAppGroup: String? {
|
||||
let appGroup = appGroups.first { $0.contains(Bundle.baseAltStoreAppGroupID) }
|
||||
return appGroup
|
||||
}
|
||||
|
||||
var completeInfoDictionary: [String: Any]? {
|
||||
let infoPlistURL = self.infoPlistURL
|
||||
return NSDictionary(contentsOf: infoPlistURL) as? [String: Any]
|
||||
}
|
||||
}
|
||||
128
SideStoreApp/Sources/Shared/Extensions/NSError+AltStore.swift
Normal file
128
SideStoreApp/Sources/Shared/Extensions/NSError+AltStore.swift
Normal file
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// NSError+AltStore.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Riley Testut on 3/11/20.
|
||||
// Copyright © 2020 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension NSError {
|
||||
@objc(alt_localizedFailure)
|
||||
var localizedFailure: String? {
|
||||
let localizedFailure = (userInfo[NSLocalizedFailureErrorKey] as? String) ?? (NSError.userInfoValueProvider(forDomain: domain)?(self, NSLocalizedFailureErrorKey) as? String)
|
||||
return localizedFailure
|
||||
}
|
||||
|
||||
@objc(alt_localizedDebugDescription)
|
||||
var localizedDebugDescription: String? {
|
||||
let debugDescription = (userInfo[NSDebugDescriptionErrorKey] as? String) ?? (NSError.userInfoValueProvider(forDomain: domain)?(self, NSDebugDescriptionErrorKey) as? String)
|
||||
return debugDescription
|
||||
}
|
||||
|
||||
@objc(alt_errorWithLocalizedFailure:)
|
||||
func withLocalizedFailure(_ failure: String) -> NSError {
|
||||
var userInfo = self.userInfo
|
||||
userInfo[NSLocalizedFailureErrorKey] = failure
|
||||
|
||||
if let failureReason = localizedFailureReason {
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = failureReason
|
||||
} else if localizedFailure == nil && localizedFailureReason == nil && localizedDescription.contains(localizedErrorCode) {
|
||||
// Default localizedDescription, so replace with just the localized error code portion.
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = "(\(localizedErrorCode).)"
|
||||
} else {
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = localizedDescription
|
||||
}
|
||||
|
||||
if let localizedDescription = NSError.userInfoValueProvider(forDomain: domain)?(self, NSLocalizedDescriptionKey) as? String {
|
||||
userInfo[NSLocalizedDescriptionKey] = localizedDescription
|
||||
}
|
||||
|
||||
// Don't accidentally remove localizedDescription from dictionary
|
||||
// userInfo[NSLocalizedDescriptionKey] = NSError.userInfoValueProvider(forDomain: self.domain)?(self, NSLocalizedDescriptionKey) as? String
|
||||
|
||||
if let recoverySuggestion = localizedRecoverySuggestion {
|
||||
userInfo[NSLocalizedRecoverySuggestionErrorKey] = recoverySuggestion
|
||||
}
|
||||
|
||||
let error = NSError(domain: domain, code: code, userInfo: userInfo)
|
||||
return error
|
||||
}
|
||||
|
||||
func sanitizedForCoreData() -> NSError {
|
||||
var userInfo = self.userInfo
|
||||
userInfo[NSLocalizedFailureErrorKey] = localizedFailure
|
||||
userInfo[NSLocalizedDescriptionKey] = localizedDescription
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = localizedFailureReason
|
||||
userInfo[NSLocalizedRecoverySuggestionErrorKey] = localizedRecoverySuggestion
|
||||
|
||||
// Remove userInfo values that don't conform to NSSecureEncoding.
|
||||
userInfo = userInfo.filter { _, value in
|
||||
(value as AnyObject) is NSSecureCoding
|
||||
}
|
||||
|
||||
// Sanitize underlying errors.
|
||||
if let underlyingError = userInfo[NSUnderlyingErrorKey] as? Error {
|
||||
let sanitizedError = (underlyingError as NSError).sanitizedForCoreData()
|
||||
userInfo[NSUnderlyingErrorKey] = sanitizedError
|
||||
}
|
||||
|
||||
if #available(iOS 14.5, macOS 11.3, *), let underlyingErrors = userInfo[NSMultipleUnderlyingErrorsKey] as? [Error] {
|
||||
let sanitizedErrors = underlyingErrors.map { ($0 as NSError).sanitizedForCoreData() }
|
||||
userInfo[NSMultipleUnderlyingErrorsKey] = sanitizedErrors
|
||||
}
|
||||
|
||||
let error = NSError(domain: domain, code: code, userInfo: userInfo)
|
||||
return error
|
||||
}
|
||||
}
|
||||
|
||||
public extension Error {
|
||||
var underlyingError: Error? {
|
||||
let underlyingError = (self as NSError).userInfo[NSUnderlyingErrorKey] as? Error
|
||||
return underlyingError
|
||||
}
|
||||
|
||||
var localizedErrorCode: String {
|
||||
let localizedErrorCode = String(format: NSLocalizedString("%@ error %@", comment: ""), (self as NSError).domain, (self as NSError).code as NSNumber)
|
||||
return localizedErrorCode
|
||||
}
|
||||
}
|
||||
|
||||
public protocol ALTLocalizedError: LocalizedError, CustomNSError {
|
||||
var failure: String? { get }
|
||||
|
||||
var underlyingError: Error? { get }
|
||||
}
|
||||
|
||||
public extension ALTLocalizedError {
|
||||
var errorUserInfo: [String: Any] {
|
||||
let userInfo = ([
|
||||
NSLocalizedDescriptionKey: errorDescription,
|
||||
NSLocalizedFailureReasonErrorKey: failureReason,
|
||||
NSLocalizedFailureErrorKey: failure,
|
||||
NSUnderlyingErrorKey: underlyingError
|
||||
] as [String: Any?]).compactMapValues { $0 }
|
||||
return userInfo
|
||||
}
|
||||
|
||||
var underlyingError: Error? {
|
||||
// Error's default implementation calls errorUserInfo,
|
||||
// but ALTLocalizedError.errorUserInfo calls underlyingError.
|
||||
// Return nil to prevent infinite recursion.
|
||||
nil
|
||||
}
|
||||
|
||||
var errorDescription: String? {
|
||||
guard let errorFailure = failure else { return (underlyingError as NSError?)?.localizedDescription }
|
||||
guard let failureReason = failureReason else { return errorFailure }
|
||||
|
||||
let errorDescription = errorFailure + " " + failureReason
|
||||
return errorDescription
|
||||
}
|
||||
|
||||
var failureReason: String? { (underlyingError as NSError?)?.localizedDescription }
|
||||
var recoverySuggestion: String? { (underlyingError as NSError?)?.localizedRecoverySuggestion }
|
||||
var helpAnchor: String? { (underlyingError as NSError?)?.helpAnchor }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// NSXPCConnection+MachServices.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Riley Testut on 9/22/20.
|
||||
// Copyright © 2020 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objc private protocol XPCPrivateAPI {
|
||||
init(machServiceName: String)
|
||||
init(machServiceName: String, options: NSXPCConnection.Options)
|
||||
}
|
||||
|
||||
public extension NSXPCConnection {
|
||||
class func makeConnection(machServiceName: String) -> NSXPCConnection {
|
||||
let connection = unsafeBitCast(self, to: XPCPrivateAPI.Type.self).init(machServiceName: machServiceName, options: .privileged)
|
||||
return unsafeBitCast(connection, to: NSXPCConnection.self)
|
||||
}
|
||||
}
|
||||
|
||||
public extension NSXPCListener {
|
||||
class func makeListener(machServiceName: String) -> NSXPCListener {
|
||||
let listener = unsafeBitCast(self, to: XPCPrivateAPI.Type.self).init(machServiceName: machServiceName)
|
||||
return unsafeBitCast(listener, to: NSXPCListener.self)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Result+Conveniences.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Riley Testut on 5/22/19.
|
||||
// Copyright © 2019 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension Result {
|
||||
var value: Success? {
|
||||
switch self {
|
||||
case let .success(value): return value
|
||||
case .failure: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var error: Failure? {
|
||||
switch self {
|
||||
case .success: return nil
|
||||
case let .failure(error): return error
|
||||
}
|
||||
}
|
||||
|
||||
init(_ value: Success?, _ error: Failure?) {
|
||||
switch (value, error) {
|
||||
case let (value?, _): self = .success(value)
|
||||
case let (_, error?): self = .failure(error)
|
||||
case (nil, nil): preconditionFailure("Either value or error must be non-nil")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension Result where Success == Void {
|
||||
init(_ success: Bool, _ error: Failure?) {
|
||||
if success {
|
||||
self = .success(())
|
||||
} else if let error = error {
|
||||
self = .failure(error)
|
||||
} else {
|
||||
preconditionFailure("Error must be non-nil if success is false")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension Result {
|
||||
init<T, U>(_ values: (T?, U?), _ error: Failure?) where Success == (T, U) {
|
||||
if let value1 = values.0, let value2 = values.1 {
|
||||
self = .success((value1, value2))
|
||||
} else if let error = error {
|
||||
self = .failure(error)
|
||||
} else {
|
||||
preconditionFailure("Error must be non-nil if either provided values are nil")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user