Created
November 9, 2018 09:11
-
-
Save mremond/7c62e85e2f1ee6ae311ee039b959fcc0 to your computer and use it in GitHub Desktop.
Revisions
-
mremond created this gist
Nov 9, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,110 @@ // // MobileProvision.swift // Fluux.io // // Created by Mickaël Rémond on 03/11/2018. // Copyright © 2018 ProcessOne. // Distributed under Apache License v2 // import Foundation /* Decode mobileprovision plist file Usage: 1. To get mobileprovision data as embedded in your app: MobileProvision.read() 2. To get mobile provision data from a file on disk: MobileProvision.read(from: "my.mobileprovision") */ struct MobileProvision: Decodable { var name: String var appIDName: String var platform: [String] var isXcodeManaged: Bool? = false var creationDate: Date var expirationDate: Date var entitlements: Entitlements private enum CodingKeys : String, CodingKey { case name = "Name" case appIDName = "AppIDName" case platform = "Platform" case isXcodeManaged = "IsXcodeManaged" case creationDate = "CreationDate" case expirationDate = "ExpirationDate" case entitlements = "Entitlements" } // Sublevel: decode entitlements informations struct Entitlements: Decodable { let keychainAccessGroups: [String] let getTaskAllow: Bool let apsEnvironment: Environment private enum CodingKeys: String, CodingKey { case keychainAccessGroups = "keychain-access-groups" case getTaskAllow = "get-task-allow" case apsEnvironment = "aps-environment" } enum Environment: String, Decodable { case development, production, disabled } init(keychainAccessGroups: Array<String>, getTaskAllow: Bool, apsEnvironment: Environment) { self.keychainAccessGroups = keychainAccessGroups self.getTaskAllow = getTaskAllow self.apsEnvironment = apsEnvironment } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let keychainAccessGroups: [String] = (try? container.decode([String].self, forKey: .keychainAccessGroups)) ?? [] let getTaskAllow: Bool = (try? container.decode(Bool.self, forKey: .getTaskAllow)) ?? false let apsEnvironment: Environment = (try? container.decode(Environment.self, forKey: .apsEnvironment)) ?? .disabled self.init(keychainAccessGroups: keychainAccessGroups, getTaskAllow: getTaskAllow, apsEnvironment: apsEnvironment) } } } // Factory methods extension MobileProvision { // Read mobileprovision file embedded in app. static func read() -> MobileProvision? { let profilePath: String? = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision") guard let path = profilePath else { return nil } return read(from: path) } // Read a .mobileprovision file on disk static func read(from profilePath: String) -> MobileProvision? { guard let plistDataString = try? NSString.init(contentsOfFile: profilePath, encoding: String.Encoding.isoLatin1.rawValue) else { return nil } // Skip binary part at the start of the mobile provisionning profile let scanner = Scanner(string: plistDataString as String) guard scanner.scanUpTo("<plist", into: nil) != false else { return nil } // ... and extract plist until end of plist payload (skip the end binary part. var extractedPlist: NSString? guard scanner.scanUpTo("</plist>", into: &extractedPlist) != false else { return nil } guard let plist = extractedPlist?.appending("</plist>").data(using: .isoLatin1) else { return nil } let decoder = PropertyListDecoder() do { let provision = try decoder.decode(MobileProvision.self, from: plist) return provision } catch { // TODO: log / handle error return nil } } }