Mobileprovision.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // LoopFollow
  2. // Mobileprovision.swift
  3. // Created by Jon Fawcett on 2020-10-05.
  4. //
  5. // MobileProvision.swift
  6. // Fluux.io
  7. //
  8. // Created by Mickaël Rémond on 03/11/2018.
  9. // Copyright © 2018 ProcessOne.
  10. // Distributed under Apache License v2
  11. //
  12. import Foundation
  13. /* Decode mobileprovision plist file
  14. Usage:
  15. 1. To get mobileprovision data as embedded in your app:
  16. MobileProvision.read()
  17. 2. To get mobile provision data from a file on disk:
  18. MobileProvision.read(from: "my.mobileprovision")
  19. */
  20. struct MobileProvision: Decodable {
  21. var name: String
  22. var appIDName: String
  23. var platform: [String]
  24. var isXcodeManaged: Bool? = false
  25. var creationDate: Date
  26. var expirationDate: Date
  27. var entitlements: Entitlements
  28. private enum CodingKeys: String, CodingKey {
  29. case name = "Name"
  30. case appIDName = "AppIDName"
  31. case platform = "Platform"
  32. case isXcodeManaged = "IsXcodeManaged"
  33. case creationDate = "CreationDate"
  34. case expirationDate = "ExpirationDate"
  35. case entitlements = "Entitlements"
  36. }
  37. // Sublevel: decode entitlements informations
  38. struct Entitlements: Decodable {
  39. let keychainAccessGroups: [String]
  40. let getTaskAllow: Bool
  41. let apsEnvironment: Environment
  42. private enum CodingKeys: String, CodingKey {
  43. case keychainAccessGroups = "keychain-access-groups"
  44. case getTaskAllow = "get-task-allow"
  45. case apsEnvironment = "aps-environment"
  46. }
  47. enum Environment: String, Decodable {
  48. case development, production, disabled
  49. }
  50. init(keychainAccessGroups: [String], getTaskAllow: Bool, apsEnvironment: Environment) {
  51. self.keychainAccessGroups = keychainAccessGroups
  52. self.getTaskAllow = getTaskAllow
  53. self.apsEnvironment = apsEnvironment
  54. }
  55. init(from decoder: Decoder) throws {
  56. let container = try decoder.container(keyedBy: CodingKeys.self)
  57. let keychainAccessGroups: [String] = (try? container.decode([String].self, forKey: .keychainAccessGroups)) ?? []
  58. let getTaskAllow: Bool = (try? container.decode(Bool.self, forKey: .getTaskAllow)) ?? false
  59. let apsEnvironment: Environment = (try? container.decode(Environment.self, forKey: .apsEnvironment)) ?? .disabled
  60. self.init(keychainAccessGroups: keychainAccessGroups, getTaskAllow: getTaskAllow, apsEnvironment: apsEnvironment)
  61. }
  62. }
  63. }
  64. // Factory methods
  65. extension MobileProvision {
  66. // Read mobileprovision file embedded in app.
  67. static func read() -> MobileProvision? {
  68. let profilePath: String? = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision")
  69. guard let path = profilePath else { return nil }
  70. return read(from: path)
  71. }
  72. // Read a .mobileprovision file on disk
  73. static func read(from profilePath: String) -> MobileProvision? {
  74. guard let plistDataString = try? NSString(contentsOfFile: profilePath,
  75. encoding: String.Encoding.isoLatin1.rawValue) else { return nil }
  76. // Skip binary part at the start of the mobile provisionning profile
  77. let scanner = Scanner(string: plistDataString as String)
  78. guard scanner.scanUpTo("<plist", into: nil) != false else { return nil }
  79. // ... and extract plist until end of plist payload (skip the end binary part.
  80. var extractedPlist: NSString?
  81. guard scanner.scanUpTo("</plist>", into: &extractedPlist) != false else { return nil }
  82. guard let plist = extractedPlist?.appending("</plist>").data(using: .isoLatin1) else { return nil }
  83. let decoder = PropertyListDecoder()
  84. do {
  85. let provision = try decoder.decode(MobileProvision.self, from: plist)
  86. return provision
  87. } catch {
  88. return nil
  89. }
  90. }
  91. }