2019-07-24 12:23:54 -07:00
|
|
|
//
|
|
|
|
|
// AppPermission.swift
|
|
|
|
|
// AltStore
|
|
|
|
|
//
|
|
|
|
|
// Created by Riley Testut on 7/23/19.
|
|
|
|
|
// Copyright © 2019 Riley Testut. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import CoreData
|
|
|
|
|
import UIKit
|
|
|
|
|
|
2023-05-12 18:26:24 -05:00
|
|
|
import AltSign
|
|
|
|
|
|
|
|
|
|
@objc(AppPermission) @dynamicMemberLookup
|
|
|
|
|
public class AppPermission: NSManagedObject, Decodable, Fetchable
|
2019-07-24 12:23:54 -07:00
|
|
|
{
|
2023-05-12 18:26:24 -05:00
|
|
|
/* Properties */
|
|
|
|
|
@NSManaged public var type: ALTAppPermissionType
|
2023-05-30 14:24:35 -05:00
|
|
|
|
|
|
|
|
// usageDescription must be non-optional for backwards compatibility,
|
|
|
|
|
// so we store non-optional value and provide public accessor with optional return type.
|
|
|
|
|
@nonobjc public var usageDescription: String? {
|
|
|
|
|
get { _usageDescription.isEmpty ? nil : _usageDescription }
|
|
|
|
|
set { _usageDescription = newValue ?? "" }
|
|
|
|
|
}
|
|
|
|
|
@NSManaged @objc(usageDescription) private var _usageDescription: String
|
2019-07-24 12:23:54 -07:00
|
|
|
|
2023-05-12 18:26:24 -05:00
|
|
|
@nonobjc public var permission: any ALTAppPermission {
|
|
|
|
|
switch self.type
|
2019-07-24 12:23:54 -07:00
|
|
|
{
|
2023-05-12 18:26:24 -05:00
|
|
|
case .entitlement: return ALTEntitlement(rawValue: self._permission)
|
|
|
|
|
case .privacy: return ALTAppPrivacyPermission(rawValue: self._permission)
|
|
|
|
|
default: return UnknownAppPermission(rawValue: self._permission)
|
2019-07-24 12:23:54 -07:00
|
|
|
}
|
|
|
|
|
}
|
2023-05-12 18:26:24 -05:00
|
|
|
@NSManaged @objc(permission) private var _permission: String
|
2019-07-24 12:23:54 -07:00
|
|
|
|
2023-05-12 18:26:24 -05:00
|
|
|
// Set by StoreApp.
|
2023-05-30 15:28:26 -05:00
|
|
|
@NSManaged public var appBundleID: String
|
|
|
|
|
@NSManaged public var sourceID: String
|
2019-07-24 12:23:54 -07:00
|
|
|
|
|
|
|
|
/* Relationships */
|
2023-05-12 18:26:24 -05:00
|
|
|
@NSManaged public internal(set) var app: StoreApp?
|
2019-07-24 12:23:54 -07:00
|
|
|
|
|
|
|
|
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?)
|
|
|
|
|
{
|
|
|
|
|
super.init(entity: entity, insertInto: context)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private enum CodingKeys: String, CodingKey
|
|
|
|
|
{
|
2023-05-30 12:57:45 -05:00
|
|
|
case name
|
2019-07-24 12:23:54 -07:00
|
|
|
case usageDescription
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-03 16:39:08 -07:00
|
|
|
public required init(from decoder: Decoder) throws
|
2019-07-24 12:23:54 -07:00
|
|
|
{
|
|
|
|
|
guard let context = decoder.managedObjectContext else { preconditionFailure("Decoder must have non-nil NSManagedObjectContext.") }
|
|
|
|
|
|
2020-08-27 16:23:50 -07:00
|
|
|
super.init(entity: AppPermission.entity(), insertInto: context)
|
2019-07-24 12:23:54 -07:00
|
|
|
|
2020-08-27 16:23:50 -07:00
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
|
|
|
|
2023-05-30 12:57:45 -05:00
|
|
|
self._permission = try container.decode(String.self, forKey: .name)
|
2023-05-12 18:26:24 -05:00
|
|
|
self.usageDescription = try container.decodeIfPresent(String.self, forKey: .usageDescription)
|
|
|
|
|
|
2023-05-30 12:57:45 -05:00
|
|
|
// Will be updated from StoreApp.
|
|
|
|
|
self.type = .unknown
|
2020-08-27 16:23:50 -07:00
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
if let context = self.managedObjectContext
|
|
|
|
|
{
|
|
|
|
|
context.delete(self)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw error
|
|
|
|
|
}
|
2019-07-24 12:23:54 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-03 16:39:08 -07:00
|
|
|
public extension AppPermission
|
2019-07-24 12:23:54 -07:00
|
|
|
{
|
|
|
|
|
@nonobjc class func fetchRequest() -> NSFetchRequest<AppPermission>
|
|
|
|
|
{
|
|
|
|
|
return NSFetchRequest<AppPermission>(entityName: "AppPermission")
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-12 18:26:24 -05:00
|
|
|
|
|
|
|
|
// @dynamicMemberLookup
|
|
|
|
|
public extension AppPermission
|
|
|
|
|
{
|
|
|
|
|
// Convenience for accessing .permission properties.
|
|
|
|
|
subscript<T>(dynamicMember keyPath: KeyPath<any ALTAppPermission, T>) -> T {
|
|
|
|
|
get {
|
|
|
|
|
return self.permission[keyPath: keyPath]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|