├── Cartfile ├── logo.png ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── ApplicationGroupKit.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ ├── ApplicationGroupKit.xcscheme │ │ ├── ApplicationGroupKitOSX.xcscheme │ │ └── ApplicationGroupKitTVOS.xcscheme └── project.pbxproj ├── ApplicationGroupKit.xcworkspace └── contents.xcworkspacedata ├── Podfile ├── Package.resolved ├── Xcode ├── iOS │ ├── ApplicationGroupKit.h │ └── Info.plist ├── macOS │ ├── ApplicationGroupKitOSX.h │ └── Info.plist └── tvOS │ ├── ApplicationGroupKitTVOS.h │ └── Info.plist ├── Package.swift ├── Sources ├── KeyChainMessenger.swift ├── ApplicationGroup+Prephirences.swift ├── UserDefaultsMessenger.swift ├── PreferencesMessenger.swift ├── MessengerType.swift ├── Messenger.swift ├── FileCoordinatorMessenger.swift ├── DarwinNotificationCenter.swift ├── FileMessenger.swift └── ApplicationGroup.swift ├── LICENSE ├── ApplicationGroupKit.podspec └── README.md /Cartfile: -------------------------------------------------------------------------------- 1 | 2 | github "phimage/Prephirences" 3 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phimage/ApplicationGroupKit/HEAD/logo.png -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ApplicationGroupKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ApplicationGroupKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | inhibit_all_warnings! 3 | 4 | def common_pods 5 | pod 'Prephirences' 6 | end 7 | 8 | target 'ApplicationGroupKit' do 9 | common_pods 10 | end 11 | 12 | target 'ApplicationGroupKitOSX' do 13 | common_pods 14 | end 15 | 16 | target 'ApplicationGroupKitTVOS' do 17 | common_pods 18 | end 19 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "Prephirences", 6 | "repositoryURL": "https://github.com/phimage/Prephirences.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "81b4792293972ec7541a941333e584ccc7976198", 10 | "version": "5.1.0" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /Xcode/iOS/ApplicationGroupKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationGroupKit.h 3 | // ApplicationGroupKit 4 | // 5 | // Created by phimage on 05/01/16. 6 | // Copyright © 2016 phimage. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ApplicationGroupKit. 12 | FOUNDATION_EXPORT double ApplicationGroupKitVersionNumber; 13 | 14 | //! Project version string for ApplicationGroupKit. 15 | FOUNDATION_EXPORT const unsigned char ApplicationGroupKitVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Xcode/macOS/ApplicationGroupKitOSX.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationGroupKitOSX.h 3 | // ApplicationGroupKitOSX 4 | // 5 | // Created by phimage on 05/01/16. 6 | // Copyright © 2016 phimage. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ApplicationGroupKitOSX. 12 | FOUNDATION_EXPORT double ApplicationGroupKitOSXVersionNumber; 13 | 14 | //! Project version string for ApplicationGroupKitOSX. 15 | FOUNDATION_EXPORT const unsigned char ApplicationGroupKitOSXVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Xcode/tvOS/ApplicationGroupKitTVOS.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationGroupKitTVOS.h 3 | // ApplicationGroupKitTVOS 4 | // 5 | // Created by phimage on 05/01/16. 6 | // Copyright © 2016 phimage. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ApplicationGroupKitTVOS. 12 | FOUNDATION_EXPORT double ApplicationGroupKitTVOSVersionNumber; 13 | 14 | //! Project version string for ApplicationGroupKitTVOS. 15 | FOUNDATION_EXPORT const unsigned char ApplicationGroupKitTVOSVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "ApplicationGroupKit", 7 | platforms: [ 8 | .macOS(.v10_11), 9 | .iOS(.v9), 10 | .tvOS(.v9), 11 | .watchOS(.v3) 12 | ], 13 | products: [ 14 | .library(name: "ApplicationGroupKit", targets: ["ApplicationGroupKit"]) 15 | ], 16 | dependencies: [ 17 | .package(url: "https://github.com/phimage/Prephirences.git", .upToNextMajor(from: "5.1.0")), 18 | ], 19 | targets: [ 20 | .target(name: "ApplicationGroupKit", dependencies: [ "Prephirences"], path: "Sources") 21 | ] 22 | ) 23 | -------------------------------------------------------------------------------- /Sources/KeyChainMessenger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyChainMessenger.swift 3 | // ApplicationGroupKit 4 | // 5 | // Created by phimage on 01/02/16. 6 | // Copyright © 2016 phimage. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Prephirences 11 | 12 | open class KeyChainMessenger: PreferencesMessenger { 13 | let service: String 14 | 15 | public init(service: String) { 16 | self.service = service 17 | super.init() 18 | } 19 | 20 | open override var preferences: MutablePreferencesType? { 21 | return self.applicationGroup?.keyChain(service) 22 | } 23 | 24 | open override var type: MessengerType { 25 | return .keyChain(service: self.service) 26 | } 27 | 28 | override func checkConfig() -> Bool { 29 | return preferences != nil 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Xcode/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Xcode/tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Xcode/macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2016 phimage. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Sources/ApplicationGroup+Prephirences.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationGroup+Prephirences.swift 3 | // ApplicationGroupKit 4 | // 5 | // Created by phimage on 03/02/16. 6 | // Copyright © 2016 phimage. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Prephirences 11 | 12 | extension ApplicationGroup: MutablePreferencesType { 13 | 14 | public func object(forKey key: PreferenceKey) -> PreferenceObject? { 15 | return self.messageForIdentifier(key) 16 | } 17 | 18 | public func dictionary() -> PreferencesDictionary { 19 | return self.messages ?? [:] 20 | } 21 | 22 | public func set(_ value: PreferenceObject?, forKey key: PreferenceKey) { 23 | if let message = value as? Message { 24 | self.postMessage(message, withIdentifier: key) 25 | } else { 26 | self.removeObject(forKey: key) 27 | } 28 | } 29 | 30 | public func removeObject(forKey key: PreferenceKey) { 31 | do { 32 | try self.clearForIdentifier(key) 33 | } catch let e { 34 | print("Failed to remove key \(key): \(e)") 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Eric Marchand (phimage) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /ApplicationGroupKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 4 | s.name = "ApplicationGroupKit" 5 | s.version = "1.0.0" 6 | s.summary = "Share information between your applications and extensions" 7 | s.homepage = "https://github.com/phimage/ApplicationGroupKit" 8 | 9 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 10 | s.license = "MIT" 11 | 12 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 13 | s.author = { "phimage" => "eric.marchand.n7@gmail.com" } 14 | 15 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 16 | s.ios.deployment_target = '9.0' 17 | s.osx.deployment_target = '10.11' 18 | s.tvos.deployment_target = '9.0' 19 | s.watchos.deployment_target = '9.0' 20 | 21 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 22 | s.source = { :git => "https://github.com/phimage/ApplicationGroupKit.git", :tag => s.version } 23 | 24 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 25 | 26 | s.default_subspecs = 'Core' 27 | 28 | s.subspec "Core" do |sp| 29 | sp.source_files = "Sources/*.swift" 30 | end 31 | 32 | s.dependency 'Prephirences' 33 | 34 | end 35 | -------------------------------------------------------------------------------- /Sources/UserDefaultsMessenger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserDefaultsMessenger.swift 3 | // ApplicationGroupKit 4 | /* 5 | The MIT License (MIT) 6 | 7 | Copyright (c) 2015 Eric Marchand (phimage) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | import Foundation 29 | import Prephirences 30 | 31 | open class UserDefaultsMessenger: PreferencesMessenger { 32 | 33 | public override init() { 34 | super.init() 35 | } 36 | 37 | open override var type: MessengerType { 38 | return .userDefaults 39 | } 40 | 41 | open override var preferences: MutablePreferencesType? { 42 | return self.applicationGroup?.userDefaults 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Sources/PreferencesMessenger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesMessenger.swift 3 | // ApplicationGroupKit 4 | // 5 | // Created by phimage on 03/02/16. 6 | // Copyright © 2016 phimage. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Prephirences 11 | 12 | // abstract class 13 | open class PreferencesMessenger: Messenger { 14 | 15 | open var preferences: MutablePreferencesType? { 16 | fatalError("Must be overrided") 17 | } 18 | 19 | open override var type: MessengerType { 20 | fatalError("Must be overrided") 21 | // return .Custom(self) 22 | } 23 | 24 | override func checkConfig() -> Bool { 25 | return preferences != nil 26 | } 27 | 28 | override func writeMessage(_ message: Message, forIdentifier identifier: MessageIdentifier) -> Bool { 29 | let data = dataFromMessage(message) 30 | guard let preferences = self.preferences else { 31 | return false 32 | } 33 | preferences.set(data, forKey: identifier) 34 | return true 35 | } 36 | 37 | override func readMessageForIdentifier(_ identifier: MessageIdentifier) -> Message? { 38 | guard let data = self.preferences?.object(forKey: identifier) as? Data else { 39 | return nil 40 | } 41 | return messageFromData(data) 42 | } 43 | 44 | override func deleteContentForIdentifier(_ identifier: MessageIdentifier) throws { 45 | self.preferences?.removeObject(forKey:identifier) 46 | } 47 | 48 | override func deleteContentForAllMessageIdentifiers() throws { 49 | if let keys = self.preferences?.dictionary().keys { 50 | for key in keys { 51 | self.preferences?.removeObject(forKey: key) 52 | } 53 | } 54 | } 55 | 56 | override func readMessages() -> [MessageIdentifier: Message]? { 57 | guard let preferences = self.preferences else { 58 | return nil 59 | } 60 | 61 | var messageLists: [MessageIdentifier: Message] = [:] 62 | for (identifier, message) in preferences.dictionary() { 63 | if let message = message as? Message { 64 | messageLists[identifier] = message 65 | } 66 | } 67 | return messageLists 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /Sources/MessengerType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessengerType.swift 3 | // ApplicationGroupKit 4 | /* 5 | The MIT License (MIT) 6 | 7 | Copyright (c) 2015 Eric Marchand (phimage) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | import Foundation 29 | 30 | public enum MessengerType { 31 | case userDefaults 32 | case file(directory: String?) 33 | case fileCoordinator(directory: String?, fileCoordinator: NSFileCoordinator) 34 | case keyChain(service: String) 35 | // case WatchKitSession 36 | case custom(Messenger) 37 | } 38 | 39 | extension MessengerType: CustomStringConvertible { 40 | public var description: String { 41 | switch self { 42 | case .userDefaults: 43 | return "UserDefaults" 44 | case .file(let directory): 45 | if let d = directory { 46 | return "File(\(d)" 47 | } 48 | return "File" 49 | case .fileCoordinator(let directory, _): 50 | if let d = directory { 51 | return "FileCoordinator(\(d)" 52 | } 53 | return "FileCoordinator" 54 | case .keyChain(let service): 55 | return "KeyChain(\(service)" 56 | case .custom(let messenger): 57 | return "Custom(\(messenger))" 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ApplicationGroupKit.xcodeproj/xcshareddata/xcschemes/ApplicationGroupKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /ApplicationGroupKit.xcodeproj/xcshareddata/xcschemes/ApplicationGroupKitOSX.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Sources/Messenger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Messenger.swift 3 | // ApplicationGroupKit 4 | // 5 | // Created by phimage on 05/01/16. 6 | // Copyright © 2016 phimage. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // Object to send 12 | public typealias Message = NSCoding 13 | // Key/identifier of message 14 | public typealias MessageIdentifier = String 15 | 16 | // Object returned when starting to listen to app group message used to cancel observation 17 | open class MessageObserver: NSObject { 18 | open var messenger: Messenger 19 | open var identifier: String 20 | 21 | init(messenger: Messenger, identifier: String) { 22 | self.messenger = messenger 23 | self.identifier = identifier 24 | } 25 | 26 | } 27 | 28 | // Abtract class which define how to send message and listen to it 29 | open class Messenger { 30 | 31 | var applicationGroup: ApplicationGroup? 32 | 33 | init() { 34 | } 35 | 36 | open func postMessage(_ message: Message, withIdentifier identifier: MessageIdentifier) { 37 | assert(!identifier.isEmpty) 38 | if writeMessage(message, forIdentifier: identifier) { 39 | DarwinNotificationCenter.defaultCenter.post(name: identifier) 40 | } 41 | } 42 | 43 | open func observeMessageForIdentifier(_ identifier: MessageIdentifier, closure: @escaping (Message) -> Void ) -> MessageObserver { 44 | let listener = MessageObserver(messenger: self, identifier: identifier) 45 | DarwinNotificationCenter.defaultCenter.addObserver(for: identifier, object: listener) { () -> Void in 46 | if let message = self.readMessageForIdentifier(identifier) { 47 | closure(message) 48 | } 49 | } 50 | return listener 51 | } 52 | 53 | open func removeObserver(_ observer: MessageObserver) { 54 | DarwinNotificationCenter.defaultCenter.remove(observer: observer) 55 | } 56 | 57 | open func messageForIdentifier(_ identifier: MessageIdentifier) -> Message? { 58 | assert(!identifier.isEmpty) 59 | return self.readMessageForIdentifier(identifier) 60 | } 61 | 62 | internal func dataFromMessage(_ message: Message) -> Data { 63 | return NSKeyedArchiver.archivedData(withRootObject: message) 64 | } 65 | 66 | internal func messageFromData(_ data: Data) -> Message? { 67 | return NSKeyedUnarchiver.unarchiveObject(with: data) as? Message 68 | } 69 | 70 | // MARK: abstracts 71 | open var type: MessengerType { 72 | fatalError("must be overrided") 73 | } 74 | func checkConfig() -> Bool { 75 | fatalError("must be overrided") 76 | } 77 | 78 | func writeMessage(_ message: Message, forIdentifier identifier: MessageIdentifier) -> Bool { 79 | fatalError("must be overrided") 80 | } 81 | 82 | func readMessageForIdentifier(_ identifier: MessageIdentifier) -> Message? { 83 | fatalError("must be overrided") 84 | } 85 | 86 | func deleteContentForIdentifier(_ identifier: MessageIdentifier) throws { 87 | fatalError("must be overrided") 88 | } 89 | 90 | func deleteContentForAllMessageIdentifiers() throws { 91 | fatalError("must be overrided") 92 | } 93 | 94 | func readMessages() -> [MessageIdentifier: Message]? { 95 | fatalError("must be overrided") 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ApplicationGroupKit.xcodeproj/xcshareddata/xcschemes/ApplicationGroupKitTVOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ApplicationGroupKit 2 | 3 | [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat 4 | )](http://mit-license.org) 5 | [![Platform](http://img.shields.io/badge/platform-ios_osx_tvos-lightgrey.svg?style=flat 6 | )](https://developer.apple.com/resources/) 7 | [![Language](http://img.shields.io/badge/language-swift-orange.svg?style=flat 8 | )](https://developer.apple.com/swift) 9 | [![Issues](https://img.shields.io/github/issues/phimage/ApplicationGroupKit.svg?style=flat 10 | )](https://github.com/phimage/ApplicationGroupKit/issues) 11 | [![Cocoapod](http://img.shields.io/cocoapods/v/ApplicationGroupKit.svg?style=flat)](http://cocoadocs.org/docsets/ApplicationGroupKit/) 12 | [![Join the chat at https://gitter.im/phimage/ApplicationGroupKit](https://img.shields.io/badge/GITTER-join%20chat-00D06F.svg)](https://gitter.im/phimage/ApplicationGroupKit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 13 | 14 | [](#logo) Applications communication using group identifier. 15 | ```swift 16 | let appGroup = ApplicationGroup(identifier: "group.id") 17 | appGroup.postMessage("your message", withIdentifier: "key") 18 | ``` 19 | ```swift 20 | appGroup.observeMessageForIdentifier("key") { message in 21 | ... 22 | } 23 | ``` 24 | 25 | ## Usage 26 | 27 | The data sharing between applications and extensions require you to enable App Group or Keychain sharing (if using key chain messenger type): 28 | - [Configuring App Groups](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html#//apple_ref/doc/uid/TP40012582-CH26-SW61) 29 | - [Configuring Keychain Sharing](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html#//apple_ref/doc/uid/TP40012582-CH26-SW15) 30 | 31 | Then you must create an `ApplicationGroup` object. 32 | ```swift 33 | let appGroup = ApplicationGroup(identifier: "your.application.group.id")! 34 | ``` 35 | You can choose the way the messages are transferred by choosing one of the `MessengerType` enum value (`File`, `UserDefaults`, `FileCoordinator`, `KeyChain`, ...) 36 | ```swift 37 | let appGroup = ApplicationGroup(identifier: "..", messengerType: .UserDefaults)! 38 | ``` 39 | :warning: `ApplicationGroup` could return `nil` if you misconfigured application group. 40 | 41 | ### Post a message 42 | 43 | Choose a message identifier and post any `NSCoding` compliant object 44 | ```swift 45 | appGroup.postMessage("your message", withIdentifier: "key to identify message") 46 | ``` 47 | 48 | #### Using subscript 49 | ```swift 50 | appGroup["key to identify message"] = "your message" 51 | ``` 52 | 53 | ### Receive a message 54 | Using the same message identifier you can receive message into callback 55 | ```swift 56 | appGroup.observeMessageForIdentifier("key to identify message") { message in 57 | .. 58 | } 59 | ``` 60 | ### Read a message 61 | You can read current value using same message identifier 62 | ```swift 63 | if let message = appGroup.messageForIdentifier("key to identify message") { 64 | .. 65 | } 66 | ``` 67 | #### Using subscript 68 | ```swift 69 | if let message = appGroup["key to identify message"] as? String { .. } 70 | ``` 71 | ## Todo 72 | - Tests 73 | - WatchKit (WatchConnectivity/WCSession...) 74 | - Carthage: let me know if carthage work and I will add the shell.io badges and installation instruction 75 | 76 | ## Contribute 77 | I am more than happy to accept external contributions to the project in the form of feedback, bug reports and even better pull requests. 78 | 79 | Implement WatchKit features and I will add you to the project (I have no need and time to do it now) 80 | 81 | ## Installation 82 | 83 | ## Using CocoaPods ## 84 | [CocoaPods](https://cocoapods.org/) is a centralized dependency manager for 85 | Objective-C and Swift. Go [here](https://guides.cocoapods.org/using/index.html) 86 | to learn more. 87 | 88 | 1. Add the project to your [Podfile](https://guides.cocoapods.org/using/the-podfile.html). 89 | 90 | ```ruby 91 | use_frameworks! 92 | 93 | pod 'ApplicationGroupKit' 94 | ``` 95 | 96 | 2. Run `pod install` and open the `.xcworkspace` file to launch Xcode. 97 | -------------------------------------------------------------------------------- /Sources/FileCoordinatorMessenger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FileCoordinatorMessenger.swift 3 | // ApplicationGroupKit 4 | /* 5 | The MIT License (MIT) 6 | 7 | Copyright (c) 2015 Eric Marchand (phimage) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | import Foundation 29 | 30 | open class FileCoordinatorMessenger: FileMessenger { 31 | 32 | let fileCoordinator: NSFileCoordinator 33 | 34 | public init(directory: String?, fileCoordinator: NSFileCoordinator) { 35 | self.fileCoordinator = fileCoordinator 36 | super.init(directory: directory) 37 | } 38 | 39 | open override var type: MessengerType { 40 | return .fileCoordinator(directory: directory, fileCoordinator: fileCoordinator) 41 | } 42 | 43 | override func writeMessage(_ message: Message, forIdentifier identifier: MessageIdentifier) -> Bool { 44 | guard let url = fileURLForIdentifier(identifier) else { 45 | return false 46 | } 47 | 48 | let data = dataFromMessage(message) 49 | 50 | var success = false 51 | var error: NSError? 52 | fileCoordinator.coordinate(writingItemAt: url, options: [], error: &error) { (url) -> Void in 53 | do { 54 | try data.write(to: url, options: []) 55 | success = true 56 | } catch { 57 | success = false 58 | } 59 | } 60 | if error != nil { 61 | return false 62 | } 63 | 64 | return success 65 | } 66 | 67 | override func readMessageForIdentifier(_ identifier: MessageIdentifier) -> Message? { 68 | guard let url = fileURLForIdentifier(identifier) else { 69 | return nil 70 | } 71 | 72 | var readData: Data? = nil 73 | var error: NSError? 74 | fileCoordinator.coordinate(readingItemAt: url, options: [], error: &error) { (url) -> Void in 75 | readData = try? Data(contentsOf: url) 76 | } 77 | if error != nil { 78 | return nil 79 | } 80 | guard let data = readData else { 81 | return nil 82 | } 83 | return messageFromData(data) 84 | } 85 | 86 | override func readMessages() -> [MessageIdentifier: Message]? { 87 | guard let url = applicationGroup?.containerURLForSecurity(fileManager) else { 88 | return nil 89 | } 90 | 91 | var messages = [MessageIdentifier: Message]() 92 | var error: NSError? 93 | fileCoordinator.coordinate(readingItemAt: url, options: [], error: &error) { (url) -> Void in 94 | guard let contents = try? self.fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: []) else { 95 | return 96 | } 97 | for content in contents { 98 | let path = content.absoluteString // XXX use absoluteString or path? 99 | if let messageIdenfier = content.pathComponents.last, 100 | let message = self.messageFromFile(path) { 101 | messages[messageIdenfier] = message 102 | } 103 | } 104 | } 105 | if error != nil { 106 | return nil 107 | } 108 | 109 | return messages 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /Sources/DarwinNotificationCenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DarwinNotificationCenter 3 | // ApplicationGroupKit 4 | /* 5 | The MIT License (MIT) 6 | 7 | Copyright (c) 2015 Eric Marchand (phimage) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | import Foundation 28 | 29 | open class DarwinNotificationCenter { 30 | 31 | public static var defaultCenter = DarwinNotificationCenter() 32 | 33 | fileprivate var observers: [String: Set] = [:] 34 | 35 | fileprivate init() {} 36 | deinit { 37 | if let center = CFNotificationCenterGetDarwinNotifyCenter() { 38 | CFNotificationCenterRemoveEveryObserver(center, Unmanaged.passUnretained(self).toOpaque()) 39 | } 40 | } 41 | 42 | open func addObserver(for name: String, object: ObserverObject, usingBlock block: @escaping () -> Void) { 43 | var handles = observers[name] ?? Set() 44 | handles.insert(Observer(object: object, block: block)) 45 | observers.updateValue(handles, forKey: name) 46 | 47 | if let center = CFNotificationCenterGetDarwinNotifyCenter() { 48 | let callback: CFNotificationCallback = { (center, observer, cfname, object, userInfo) in 49 | guard let name = (cfname?.rawValue as String?) else { return } 50 | DarwinNotificationCenter.defaultCenter.notification(with: name) 51 | } 52 | 53 | CFNotificationCenterAddObserver(center, Unmanaged.passUnretained(self).toOpaque(), callback, name as CFString, nil, CFNotificationSuspensionBehavior.deliverImmediately) 54 | } 55 | } 56 | 57 | open func post(name: String) { 58 | if let center = CFNotificationCenterGetDarwinNotifyCenter() { 59 | let cfName = name as CFString 60 | CFNotificationCenterPostNotificationWithOptions(center, CFNotificationName(rawValue: cfName), nil, nil, UInt(kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions)) 61 | } 62 | } 63 | 64 | open func remove(observer: ObserverObject) { 65 | for name in observers.keys { 66 | remove(observer: observer, name: name) 67 | } 68 | } 69 | 70 | open func remove(observer: ObserverObject, name: String) { 71 | var handles = observers[name] ?? Set() 72 | handles = Set(handles.filter { (item) -> Bool in 73 | return !item.object.isEqual(observer) 74 | }) 75 | if handles.isEmpty { 76 | observers.removeValue(forKey: name) 77 | } else { 78 | observers.updateValue(handles, forKey: name) 79 | } 80 | } 81 | 82 | // MARK - privates 83 | fileprivate func notification(with name: String) { 84 | let observers = self.observers[name] ?? Set() 85 | for observer in observers { 86 | observer.block() 87 | } 88 | } 89 | 90 | } 91 | 92 | // MARK: Observer 93 | 94 | public typealias ObserverObject = NSObjectProtocol 95 | private struct Observer { 96 | var object: ObserverObject // or Hashable (but work only with generic constraint 97 | var block: () -> Void 98 | 99 | init(object: ObserverObject, block: @escaping () -> Void) { 100 | self.object = object 101 | self.block = block 102 | } 103 | } 104 | 105 | extension Observer: Hashable { 106 | 107 | func hash(into hasher: inout Hasher) { 108 | hasher.combine(object.hash) 109 | } 110 | } 111 | private func == (lhs: Observer, rhs: Observer) -> Bool { 112 | return lhs.object.isEqual(rhs.object) 113 | } 114 | -------------------------------------------------------------------------------- /Sources/FileMessenger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FileMessenger.swift 3 | // ApplicationGroupKit 4 | /* 5 | The MIT License (MIT) 6 | 7 | Copyright (c) 2015 Eric Marchand (phimage) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | import Foundation 29 | 30 | open class FileMessenger: Messenger { 31 | 32 | open var fileManager = FileManager.default 33 | open var directory: String? 34 | 35 | public init(directory: String?) { 36 | super.init() 37 | self.directory = directory 38 | } 39 | 40 | open override var type: MessengerType { 41 | return .file(directory: directory) 42 | } 43 | 44 | override func checkConfig() -> Bool { 45 | guard let url = containerURLForSecurity() else { 46 | return false 47 | } 48 | do { 49 | try fileManager.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) 50 | } catch { 51 | return false 52 | } 53 | return true 54 | } 55 | 56 | override func writeMessage(_ message: Message, forIdentifier identifier: MessageIdentifier) -> Bool { 57 | guard let path = filePathForIdentifier(identifier) else { 58 | return false 59 | } 60 | 61 | return NSKeyedArchiver.archiveRootObject(message, toFile: path) 62 | } 63 | 64 | override func readMessageForIdentifier(_ identifier: MessageIdentifier) -> Message? { 65 | guard let path = filePathForIdentifier(identifier) else { 66 | return nil 67 | } 68 | 69 | return messageFromFile(path) 70 | } 71 | 72 | override func deleteContentForIdentifier(_ identifier: MessageIdentifier) throws { 73 | guard let path = filePathForIdentifier(identifier) else { 74 | return 75 | } 76 | var isDirectory: ObjCBool = false 77 | if self.fileManager.fileExists(atPath: path, isDirectory: &isDirectory) { 78 | if !isDirectory.boolValue { 79 | try self.fileManager.removeItem(atPath: path) 80 | } 81 | } 82 | } 83 | 84 | override func deleteContentForAllMessageIdentifiers() throws { 85 | guard let url = containerURLForSecurity() else { 86 | return 87 | } 88 | let contents = try fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: []) 89 | for content in contents { 90 | var isDirectory: ObjCBool = false 91 | if self.fileManager.fileExists(atPath: content.absoluteString, isDirectory: &isDirectory) { 92 | if !isDirectory.boolValue { 93 | try self.fileManager.removeItem(at: content) 94 | } 95 | } 96 | } 97 | } 98 | 99 | override func readMessages() -> [MessageIdentifier: Message]? { 100 | guard let url = applicationGroup?.containerURLForSecurity(fileManager) else { 101 | return nil 102 | } 103 | 104 | guard let contents = try? fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: []) else { 105 | return nil 106 | } 107 | var messages = [MessageIdentifier: Message]() 108 | for content in contents { 109 | let path = content.absoluteString // XXX use absoluteString or path? 110 | if let messageIdenfier = content.pathComponents.last, 111 | let message = messageFromFile(path) { 112 | messages[messageIdenfier] = message 113 | } 114 | } 115 | return messages 116 | } 117 | 118 | // MARK: privates 119 | internal func containerURLForSecurity() -> URL? { 120 | let container = applicationGroup?.containerURLForSecurity(fileManager) 121 | guard let directory = self.directory else { 122 | return container 123 | } 124 | return container?.appendingPathComponent(directory) 125 | } 126 | 127 | internal func fileURLForIdentifier(_ identifier: MessageIdentifier) -> URL? { 128 | return containerURLForSecurity()?.appendingPathComponent(identifier) 129 | } 130 | 131 | internal func filePathForIdentifier(_ identifier: MessageIdentifier) -> String? { 132 | guard let url = fileURLForIdentifier(identifier) else { 133 | return nil 134 | } 135 | return url.absoluteString 136 | } 137 | 138 | internal func messageFromFile(_ path: String) -> Message? { 139 | return NSKeyedUnarchiver.unarchiveObject(withFile: path) as? Message 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /Sources/ApplicationGroup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationGroup.swift 3 | // ApplicationGroupKit 4 | /* 5 | The MIT License (MIT) 6 | 7 | Copyright (c) 2015 Eric Marchand (phimage) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | import Foundation 29 | import Prephirences 30 | 31 | public typealias ApplicationGroupIdentifier = String 32 | 33 | // An application group object, defined by its identifier and the way to transfert the message 34 | open class ApplicationGroup { 35 | 36 | public let identifier: ApplicationGroupIdentifier 37 | public let messenger: Messenger 38 | 39 | public init?(identifier: ApplicationGroupIdentifier, messengerType: MessengerType = .file(directory: "appgroup")) { 40 | self.identifier = identifier 41 | switch messengerType { 42 | case .userDefaults: 43 | self.messenger = UserDefaultsMessenger() 44 | case .file(let directory): 45 | self.messenger = FileMessenger(directory: directory) 46 | case .fileCoordinator(let directory, let fileCoordinator): 47 | self.messenger = FileCoordinatorMessenger(directory: directory, fileCoordinator: fileCoordinator) 48 | case .keyChain(let service): 49 | self.messenger = KeyChainMessenger(service: service) 50 | case .custom(let messenger): 51 | self.messenger = messenger 52 | } 53 | self.messenger.applicationGroup = self 54 | 55 | if !self.messenger.checkConfig() { 56 | return nil 57 | } 58 | } 59 | 60 | // Post a message 61 | open func postMessage(_ message: Message, withIdentifier identifier: MessageIdentifier) { 62 | self.messenger.postMessage(message, withIdentifier: identifier) 63 | } 64 | 65 | // Observe message 66 | open func observeMessageForIdentifier(_ identifier: MessageIdentifier, closure: @escaping (Message) -> Void ) -> MessageObserver { 67 | return self.messenger.observeMessageForIdentifier(identifier, closure: closure) 68 | } 69 | 70 | // Get current message value if any 71 | open func messageForIdentifier(_ identifier: MessageIdentifier) -> Message? { 72 | return self.messenger.messageForIdentifier(identifier) 73 | } 74 | 75 | // Clear value for this identifier 76 | open func clearForIdentifier(_ identifier: MessageIdentifier) throws { 77 | try self.messenger.deleteContentForIdentifier(identifier) 78 | } 79 | 80 | // Clear for all message identifiers 81 | open func clearAll() throws { 82 | try self.messenger.deleteContentForAllMessageIdentifiers() 83 | } 84 | 85 | // Clear for all message identifiers 86 | open var messages: [MessageIdentifier: Message]? { 87 | return self.messenger.readMessages() 88 | } 89 | 90 | // MARK: factory of foundation objects 91 | 92 | // create a grooup user defaults 93 | open var userDefaults: UserDefaults? { 94 | return UserDefaults(suiteName: self.identifier) 95 | } 96 | 97 | // get the url for group ip 98 | open func containerURLForSecurity(_ fileManager: FileManager = FileManager.default) -> URL? { 99 | return fileManager.containerURL(forSecurityApplicationGroupIdentifier: self.identifier) 100 | } 101 | 102 | // get keychain object 103 | 104 | open func keyChain(_ service: String) -> KeychainPreferences { 105 | let keyChain = KeychainPreferences(service: service) 106 | keyChain.accessGroup = self.identifier 107 | return keyChain 108 | } 109 | 110 | // TODO WatchKit 111 | } 112 | 113 | extension ApplicationGroup: CustomStringConvertible { 114 | 115 | public var description: String { 116 | return "\(String(describing: type(of: self)))(' \(self.identifier ), \(String(describing: self.messenger.type))')" 117 | } 118 | } 119 | 120 | // WIP: allow use subscript, but not released to see if could be compatible with Prephirences 121 | extension ApplicationGroup { 122 | 123 | internal subscript(messageIdentifier: MessageIdentifier) -> Message? { 124 | get { 125 | return messageForIdentifier(messageIdentifier) 126 | } 127 | set { 128 | if let message = newValue { 129 | postMessage(message, withIdentifier: messageIdentifier) 130 | } else { 131 | do { 132 | try clearForIdentifier(identifier) 133 | } catch { 134 | print("Failed to clear group \(self) for message identifier \(identifier)") 135 | } 136 | } 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /ApplicationGroupKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 485AF2831E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2791E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift */; }; 11 | 485AF2841E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2791E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift */; }; 12 | 485AF2851E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2791E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift */; }; 13 | 485AF2861E979AD900D9DF7D /* ApplicationGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27A1E979AD900D9DF7D /* ApplicationGroup.swift */; }; 14 | 485AF2871E979AD900D9DF7D /* ApplicationGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27A1E979AD900D9DF7D /* ApplicationGroup.swift */; }; 15 | 485AF2881E979AD900D9DF7D /* ApplicationGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27A1E979AD900D9DF7D /* ApplicationGroup.swift */; }; 16 | 485AF2891E979AD900D9DF7D /* DarwinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27B1E979AD900D9DF7D /* DarwinNotificationCenter.swift */; }; 17 | 485AF28A1E979AD900D9DF7D /* DarwinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27B1E979AD900D9DF7D /* DarwinNotificationCenter.swift */; }; 18 | 485AF28B1E979AD900D9DF7D /* DarwinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27B1E979AD900D9DF7D /* DarwinNotificationCenter.swift */; }; 19 | 485AF28C1E979AD900D9DF7D /* FileCoordinatorMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27C1E979AD900D9DF7D /* FileCoordinatorMessenger.swift */; }; 20 | 485AF28D1E979AD900D9DF7D /* FileCoordinatorMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27C1E979AD900D9DF7D /* FileCoordinatorMessenger.swift */; }; 21 | 485AF28E1E979AD900D9DF7D /* FileCoordinatorMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27C1E979AD900D9DF7D /* FileCoordinatorMessenger.swift */; }; 22 | 485AF28F1E979AD900D9DF7D /* FileMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27D1E979AD900D9DF7D /* FileMessenger.swift */; }; 23 | 485AF2901E979AD900D9DF7D /* FileMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27D1E979AD900D9DF7D /* FileMessenger.swift */; }; 24 | 485AF2911E979AD900D9DF7D /* FileMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27D1E979AD900D9DF7D /* FileMessenger.swift */; }; 25 | 485AF2921E979AD900D9DF7D /* KeyChainMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27E1E979AD900D9DF7D /* KeyChainMessenger.swift */; }; 26 | 485AF2931E979AD900D9DF7D /* KeyChainMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27E1E979AD900D9DF7D /* KeyChainMessenger.swift */; }; 27 | 485AF2941E979AD900D9DF7D /* KeyChainMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27E1E979AD900D9DF7D /* KeyChainMessenger.swift */; }; 28 | 485AF2951E979AD900D9DF7D /* Messenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27F1E979AD900D9DF7D /* Messenger.swift */; }; 29 | 485AF2961E979AD900D9DF7D /* Messenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27F1E979AD900D9DF7D /* Messenger.swift */; }; 30 | 485AF2971E979AD900D9DF7D /* Messenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF27F1E979AD900D9DF7D /* Messenger.swift */; }; 31 | 485AF2981E979AD900D9DF7D /* MessengerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2801E979AD900D9DF7D /* MessengerType.swift */; }; 32 | 485AF2991E979AD900D9DF7D /* MessengerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2801E979AD900D9DF7D /* MessengerType.swift */; }; 33 | 485AF29A1E979AD900D9DF7D /* MessengerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2801E979AD900D9DF7D /* MessengerType.swift */; }; 34 | 485AF29B1E979AD900D9DF7D /* PreferencesMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2811E979AD900D9DF7D /* PreferencesMessenger.swift */; }; 35 | 485AF29C1E979AD900D9DF7D /* PreferencesMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2811E979AD900D9DF7D /* PreferencesMessenger.swift */; }; 36 | 485AF29D1E979AD900D9DF7D /* PreferencesMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2811E979AD900D9DF7D /* PreferencesMessenger.swift */; }; 37 | 485AF29E1E979AD900D9DF7D /* UserDefaultsMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2821E979AD900D9DF7D /* UserDefaultsMessenger.swift */; }; 38 | 485AF29F1E979AD900D9DF7D /* UserDefaultsMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2821E979AD900D9DF7D /* UserDefaultsMessenger.swift */; }; 39 | 485AF2A01E979AD900D9DF7D /* UserDefaultsMessenger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485AF2821E979AD900D9DF7D /* UserDefaultsMessenger.swift */; }; 40 | 5E3280B8B551FD22342629EF /* Pods_ApplicationGroupKitOSX.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 346D0C6B9896BBAA4AE3ED35 /* Pods_ApplicationGroupKitOSX.framework */; }; 41 | 81F6C6EAA2E7BFD72BF6C0C4 /* Pods_ApplicationGroupKitTVOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79F0E0374A7AB5D78DA337B9 /* Pods_ApplicationGroupKitTVOS.framework */; }; 42 | C4CC50BC1C3B36270021AA46 /* ApplicationGroupKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C4CC50BB1C3B36270021AA46 /* ApplicationGroupKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43 | C4CC50EB1C3B3E980021AA46 /* ApplicationGroupKitOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = C4CC50EA1C3B3E980021AA46 /* ApplicationGroupKitOSX.h */; settings = {ATTRIBUTES = (Public, ); }; }; 44 | C4CC50F81C3B3EB40021AA46 /* ApplicationGroupKitTVOS.h in Headers */ = {isa = PBXBuildFile; fileRef = C4CC50F71C3B3EB40021AA46 /* ApplicationGroupKitTVOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 45 | DBF335C6780CD3A0AEAFE4D7 /* Pods_ApplicationGroupKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C851F9610A04C1607A4818 /* Pods_ApplicationGroupKit.framework */; }; 46 | /* End PBXBuildFile section */ 47 | 48 | /* Begin PBXFileReference section */ 49 | 346D0C6B9896BBAA4AE3ED35 /* Pods_ApplicationGroupKitOSX.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ApplicationGroupKitOSX.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 35920FE19CF5CAA77FB8BC29 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 485AF2791E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ApplicationGroup+Prephirences.swift"; sourceTree = ""; }; 52 | 485AF27A1E979AD900D9DF7D /* ApplicationGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationGroup.swift; sourceTree = ""; }; 53 | 485AF27B1E979AD900D9DF7D /* DarwinNotificationCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DarwinNotificationCenter.swift; sourceTree = ""; }; 54 | 485AF27C1E979AD900D9DF7D /* FileCoordinatorMessenger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileCoordinatorMessenger.swift; sourceTree = ""; }; 55 | 485AF27D1E979AD900D9DF7D /* FileMessenger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileMessenger.swift; sourceTree = ""; }; 56 | 485AF27E1E979AD900D9DF7D /* KeyChainMessenger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyChainMessenger.swift; sourceTree = ""; }; 57 | 485AF27F1E979AD900D9DF7D /* Messenger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Messenger.swift; sourceTree = ""; }; 58 | 485AF2801E979AD900D9DF7D /* MessengerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessengerType.swift; sourceTree = ""; }; 59 | 485AF2811E979AD900D9DF7D /* PreferencesMessenger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesMessenger.swift; sourceTree = ""; }; 60 | 485AF2821E979AD900D9DF7D /* UserDefaultsMessenger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsMessenger.swift; sourceTree = ""; }; 61 | 4AD07F29FA0A339A2B0E1A92 /* Pods-ApplicationGroupKitOSX.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ApplicationGroupKitOSX.release.xcconfig"; path = "Pods/Target Support Files/Pods-ApplicationGroupKitOSX/Pods-ApplicationGroupKitOSX.release.xcconfig"; sourceTree = ""; }; 62 | 54B0214CD66ADDE960103E11 /* Pods-ApplicationGroupKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ApplicationGroupKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-ApplicationGroupKit/Pods-ApplicationGroupKit.release.xcconfig"; sourceTree = ""; }; 63 | 63C851F9610A04C1607A4818 /* Pods_ApplicationGroupKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ApplicationGroupKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 6717F1D200BC8E6C77704AB1 /* Pods-ApplicationGroupKitOSX.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ApplicationGroupKitOSX.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ApplicationGroupKitOSX/Pods-ApplicationGroupKitOSX.debug.xcconfig"; sourceTree = ""; }; 65 | 67893A42D2BAFC718E333E69 /* Pods-ApplicationGroupKitTVOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ApplicationGroupKitTVOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-ApplicationGroupKitTVOS/Pods-ApplicationGroupKitTVOS.release.xcconfig"; sourceTree = ""; }; 66 | 79F0E0374A7AB5D78DA337B9 /* Pods_ApplicationGroupKitTVOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ApplicationGroupKitTVOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | C4CC50B81C3B36270021AA46 /* ApplicationGroupKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ApplicationGroupKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | C4CC50BB1C3B36270021AA46 /* ApplicationGroupKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ApplicationGroupKit.h; sourceTree = ""; }; 69 | C4CC50BD1C3B36270021AA46 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 70 | C4CC50E81C3B3E980021AA46 /* ApplicationGroupKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ApplicationGroupKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 71 | C4CC50EA1C3B3E980021AA46 /* ApplicationGroupKitOSX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ApplicationGroupKitOSX.h; sourceTree = ""; }; 72 | C4CC50EC1C3B3E980021AA46 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73 | C4CC50F51C3B3EB40021AA46 /* ApplicationGroupKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ApplicationGroupKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | C4CC50F71C3B3EB40021AA46 /* ApplicationGroupKitTVOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ApplicationGroupKitTVOS.h; sourceTree = ""; }; 75 | C4CC50F91C3B3EB40021AA46 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 76 | D0D8DF972A8AD6C5258AF1A8 /* Pods-ApplicationGroupKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ApplicationGroupKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ApplicationGroupKit/Pods-ApplicationGroupKit.debug.xcconfig"; sourceTree = ""; }; 77 | E7BA5924E99AE4AE121F42F8 /* Pods-ApplicationGroupKitTVOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ApplicationGroupKitTVOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ApplicationGroupKitTVOS/Pods-ApplicationGroupKitTVOS.debug.xcconfig"; sourceTree = ""; }; 78 | /* End PBXFileReference section */ 79 | 80 | /* Begin PBXFrameworksBuildPhase section */ 81 | C4CC50B41C3B36270021AA46 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | DBF335C6780CD3A0AEAFE4D7 /* Pods_ApplicationGroupKit.framework in Frameworks */, 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | C4CC50E41C3B3E980021AA46 /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | 5E3280B8B551FD22342629EF /* Pods_ApplicationGroupKitOSX.framework in Frameworks */, 94 | ); 95 | runOnlyForDeploymentPostprocessing = 0; 96 | }; 97 | C4CC50F11C3B3EB40021AA46 /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | 81F6C6EAA2E7BFD72BF6C0C4 /* Pods_ApplicationGroupKitTVOS.framework in Frameworks */, 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | /* End PBXFrameworksBuildPhase section */ 106 | 107 | /* Begin PBXGroup section */ 108 | 3C03A0356E2498E349622265 /* Frameworks */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 35920FE19CF5CAA77FB8BC29 /* Pods.framework */, 112 | 63C851F9610A04C1607A4818 /* Pods_ApplicationGroupKit.framework */, 113 | 346D0C6B9896BBAA4AE3ED35 /* Pods_ApplicationGroupKitOSX.framework */, 114 | 79F0E0374A7AB5D78DA337B9 /* Pods_ApplicationGroupKitTVOS.framework */, 115 | ); 116 | name = Frameworks; 117 | sourceTree = ""; 118 | }; 119 | 485AF2781E979AD900D9DF7D /* Sources */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 485AF2791E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift */, 123 | 485AF27A1E979AD900D9DF7D /* ApplicationGroup.swift */, 124 | 485AF27B1E979AD900D9DF7D /* DarwinNotificationCenter.swift */, 125 | 485AF27F1E979AD900D9DF7D /* Messenger.swift */, 126 | 485AF2801E979AD900D9DF7D /* MessengerType.swift */, 127 | 485AF2A11E979AEE00D9DF7D /* MessengerType */, 128 | ); 129 | path = Sources; 130 | sourceTree = ""; 131 | }; 132 | 485AF2A11E979AEE00D9DF7D /* MessengerType */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 485AF27C1E979AD900D9DF7D /* FileCoordinatorMessenger.swift */, 136 | 485AF27D1E979AD900D9DF7D /* FileMessenger.swift */, 137 | 485AF27E1E979AD900D9DF7D /* KeyChainMessenger.swift */, 138 | 485AF2811E979AD900D9DF7D /* PreferencesMessenger.swift */, 139 | 485AF2821E979AD900D9DF7D /* UserDefaultsMessenger.swift */, 140 | ); 141 | name = MessengerType; 142 | sourceTree = ""; 143 | }; 144 | 485AF2A21E979AFB00D9DF7D /* Xcode */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | C4CC50BA1C3B36270021AA46 /* iOS */, 148 | C4CC50E91C3B3E980021AA46 /* macOS */, 149 | C4CC50F61C3B3EB40021AA46 /* tvOS */, 150 | ); 151 | path = Xcode; 152 | sourceTree = ""; 153 | }; 154 | C4CC50AE1C3B36270021AA46 = { 155 | isa = PBXGroup; 156 | children = ( 157 | 485AF2781E979AD900D9DF7D /* Sources */, 158 | 485AF2A21E979AFB00D9DF7D /* Xcode */, 159 | C4CC50B91C3B36270021AA46 /* Products */, 160 | 3C03A0356E2498E349622265 /* Frameworks */, 161 | F96EB3010262602E8CAAD084 /* Pods */, 162 | ); 163 | sourceTree = ""; 164 | }; 165 | C4CC50B91C3B36270021AA46 /* Products */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | C4CC50B81C3B36270021AA46 /* ApplicationGroupKit.framework */, 169 | C4CC50E81C3B3E980021AA46 /* ApplicationGroupKit.framework */, 170 | C4CC50F51C3B3EB40021AA46 /* ApplicationGroupKit.framework */, 171 | ); 172 | name = Products; 173 | sourceTree = ""; 174 | }; 175 | C4CC50BA1C3B36270021AA46 /* iOS */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | C4CC50BB1C3B36270021AA46 /* ApplicationGroupKit.h */, 179 | C4CC50BD1C3B36270021AA46 /* Info.plist */, 180 | ); 181 | path = iOS; 182 | sourceTree = ""; 183 | }; 184 | C4CC50E91C3B3E980021AA46 /* macOS */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | C4CC50EA1C3B3E980021AA46 /* ApplicationGroupKitOSX.h */, 188 | C4CC50EC1C3B3E980021AA46 /* Info.plist */, 189 | ); 190 | path = macOS; 191 | sourceTree = ""; 192 | }; 193 | C4CC50F61C3B3EB40021AA46 /* tvOS */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | C4CC50F71C3B3EB40021AA46 /* ApplicationGroupKitTVOS.h */, 197 | C4CC50F91C3B3EB40021AA46 /* Info.plist */, 198 | ); 199 | path = tvOS; 200 | sourceTree = ""; 201 | }; 202 | F96EB3010262602E8CAAD084 /* Pods */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | D0D8DF972A8AD6C5258AF1A8 /* Pods-ApplicationGroupKit.debug.xcconfig */, 206 | 54B0214CD66ADDE960103E11 /* Pods-ApplicationGroupKit.release.xcconfig */, 207 | 6717F1D200BC8E6C77704AB1 /* Pods-ApplicationGroupKitOSX.debug.xcconfig */, 208 | 4AD07F29FA0A339A2B0E1A92 /* Pods-ApplicationGroupKitOSX.release.xcconfig */, 209 | E7BA5924E99AE4AE121F42F8 /* Pods-ApplicationGroupKitTVOS.debug.xcconfig */, 210 | 67893A42D2BAFC718E333E69 /* Pods-ApplicationGroupKitTVOS.release.xcconfig */, 211 | ); 212 | name = Pods; 213 | sourceTree = ""; 214 | }; 215 | /* End PBXGroup section */ 216 | 217 | /* Begin PBXHeadersBuildPhase section */ 218 | C4CC50B51C3B36270021AA46 /* Headers */ = { 219 | isa = PBXHeadersBuildPhase; 220 | buildActionMask = 2147483647; 221 | files = ( 222 | C4CC50BC1C3B36270021AA46 /* ApplicationGroupKit.h in Headers */, 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | }; 226 | C4CC50E51C3B3E980021AA46 /* Headers */ = { 227 | isa = PBXHeadersBuildPhase; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | C4CC50EB1C3B3E980021AA46 /* ApplicationGroupKitOSX.h in Headers */, 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | C4CC50F21C3B3EB40021AA46 /* Headers */ = { 235 | isa = PBXHeadersBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | C4CC50F81C3B3EB40021AA46 /* ApplicationGroupKitTVOS.h in Headers */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | /* End PBXHeadersBuildPhase section */ 243 | 244 | /* Begin PBXNativeTarget section */ 245 | C4CC50B71C3B36270021AA46 /* ApplicationGroupKit */ = { 246 | isa = PBXNativeTarget; 247 | buildConfigurationList = C4CC50C01C3B36270021AA46 /* Build configuration list for PBXNativeTarget "ApplicationGroupKit" */; 248 | buildPhases = ( 249 | 92974C7F4C16DCF9D6C3964D /* [CP] Check Pods Manifest.lock */, 250 | C4CC50B31C3B36270021AA46 /* Sources */, 251 | C4CC50B41C3B36270021AA46 /* Frameworks */, 252 | C4CC50B51C3B36270021AA46 /* Headers */, 253 | C4CC50B61C3B36270021AA46 /* Resources */, 254 | 20966BD2A48FB3A193E60C1B /* [CP] Copy Pods Resources */, 255 | ); 256 | buildRules = ( 257 | ); 258 | dependencies = ( 259 | ); 260 | name = ApplicationGroupKit; 261 | productName = ApplicationGroupKit; 262 | productReference = C4CC50B81C3B36270021AA46 /* ApplicationGroupKit.framework */; 263 | productType = "com.apple.product-type.framework"; 264 | }; 265 | C4CC50E71C3B3E980021AA46 /* ApplicationGroupKitOSX */ = { 266 | isa = PBXNativeTarget; 267 | buildConfigurationList = C4CC50ED1C3B3E980021AA46 /* Build configuration list for PBXNativeTarget "ApplicationGroupKitOSX" */; 268 | buildPhases = ( 269 | 8F0742643284F9C0BEB2EF00 /* [CP] Check Pods Manifest.lock */, 270 | C4CC50E31C3B3E980021AA46 /* Sources */, 271 | C4CC50E41C3B3E980021AA46 /* Frameworks */, 272 | C4CC50E51C3B3E980021AA46 /* Headers */, 273 | C4CC50E61C3B3E980021AA46 /* Resources */, 274 | EACB67B58CA7C806ABBBDF78 /* [CP] Copy Pods Resources */, 275 | ); 276 | buildRules = ( 277 | ); 278 | dependencies = ( 279 | ); 280 | name = ApplicationGroupKitOSX; 281 | productName = ApplicationGroupKitOSX; 282 | productReference = C4CC50E81C3B3E980021AA46 /* ApplicationGroupKit.framework */; 283 | productType = "com.apple.product-type.framework"; 284 | }; 285 | C4CC50F41C3B3EB40021AA46 /* ApplicationGroupKitTVOS */ = { 286 | isa = PBXNativeTarget; 287 | buildConfigurationList = C4CC50FA1C3B3EB40021AA46 /* Build configuration list for PBXNativeTarget "ApplicationGroupKitTVOS" */; 288 | buildPhases = ( 289 | 43C79B8F17A1ED591D60AED1 /* [CP] Check Pods Manifest.lock */, 290 | C4CC50F01C3B3EB40021AA46 /* Sources */, 291 | C4CC50F11C3B3EB40021AA46 /* Frameworks */, 292 | C4CC50F21C3B3EB40021AA46 /* Headers */, 293 | C4CC50F31C3B3EB40021AA46 /* Resources */, 294 | 8AFA55F223A1523537B71956 /* [CP] Copy Pods Resources */, 295 | ); 296 | buildRules = ( 297 | ); 298 | dependencies = ( 299 | ); 300 | name = ApplicationGroupKitTVOS; 301 | productName = ApplicationGroupKitTVOS; 302 | productReference = C4CC50F51C3B3EB40021AA46 /* ApplicationGroupKit.framework */; 303 | productType = "com.apple.product-type.framework"; 304 | }; 305 | /* End PBXNativeTarget section */ 306 | 307 | /* Begin PBXProject section */ 308 | C4CC50AF1C3B36270021AA46 /* Project object */ = { 309 | isa = PBXProject; 310 | attributes = { 311 | LastSwiftUpdateCheck = 0720; 312 | LastUpgradeCheck = 0830; 313 | ORGANIZATIONNAME = phimage; 314 | TargetAttributes = { 315 | C4CC50B71C3B36270021AA46 = { 316 | CreatedOnToolsVersion = 7.2; 317 | DevelopmentTeam = GGU39CDBL2; 318 | LastSwiftMigration = 0830; 319 | }; 320 | C4CC50E71C3B3E980021AA46 = { 321 | CreatedOnToolsVersion = 7.2; 322 | LastSwiftMigration = 0830; 323 | }; 324 | C4CC50F41C3B3EB40021AA46 = { 325 | CreatedOnToolsVersion = 7.2; 326 | DevelopmentTeam = GGU39CDBL2; 327 | LastSwiftMigration = 0830; 328 | }; 329 | }; 330 | }; 331 | buildConfigurationList = C4CC50B21C3B36270021AA46 /* Build configuration list for PBXProject "ApplicationGroupKit" */; 332 | compatibilityVersion = "Xcode 3.2"; 333 | developmentRegion = English; 334 | hasScannedForEncodings = 0; 335 | knownRegions = ( 336 | en, 337 | Base, 338 | ); 339 | mainGroup = C4CC50AE1C3B36270021AA46; 340 | productRefGroup = C4CC50B91C3B36270021AA46 /* Products */; 341 | projectDirPath = ""; 342 | projectRoot = ""; 343 | targets = ( 344 | C4CC50B71C3B36270021AA46 /* ApplicationGroupKit */, 345 | C4CC50E71C3B3E980021AA46 /* ApplicationGroupKitOSX */, 346 | C4CC50F41C3B3EB40021AA46 /* ApplicationGroupKitTVOS */, 347 | ); 348 | }; 349 | /* End PBXProject section */ 350 | 351 | /* Begin PBXResourcesBuildPhase section */ 352 | C4CC50B61C3B36270021AA46 /* Resources */ = { 353 | isa = PBXResourcesBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | ); 357 | runOnlyForDeploymentPostprocessing = 0; 358 | }; 359 | C4CC50E61C3B3E980021AA46 /* Resources */ = { 360 | isa = PBXResourcesBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | ); 364 | runOnlyForDeploymentPostprocessing = 0; 365 | }; 366 | C4CC50F31C3B3EB40021AA46 /* Resources */ = { 367 | isa = PBXResourcesBuildPhase; 368 | buildActionMask = 2147483647; 369 | files = ( 370 | ); 371 | runOnlyForDeploymentPostprocessing = 0; 372 | }; 373 | /* End PBXResourcesBuildPhase section */ 374 | 375 | /* Begin PBXShellScriptBuildPhase section */ 376 | 20966BD2A48FB3A193E60C1B /* [CP] Copy Pods Resources */ = { 377 | isa = PBXShellScriptBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | ); 381 | inputPaths = ( 382 | ); 383 | name = "[CP] Copy Pods Resources"; 384 | outputPaths = ( 385 | ); 386 | runOnlyForDeploymentPostprocessing = 0; 387 | shellPath = /bin/sh; 388 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ApplicationGroupKit/Pods-ApplicationGroupKit-resources.sh\"\n"; 389 | showEnvVarsInLog = 0; 390 | }; 391 | 43C79B8F17A1ED591D60AED1 /* [CP] Check Pods Manifest.lock */ = { 392 | isa = PBXShellScriptBuildPhase; 393 | buildActionMask = 2147483647; 394 | files = ( 395 | ); 396 | inputPaths = ( 397 | ); 398 | name = "[CP] Check Pods Manifest.lock"; 399 | outputPaths = ( 400 | ); 401 | runOnlyForDeploymentPostprocessing = 0; 402 | shellPath = /bin/sh; 403 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 404 | showEnvVarsInLog = 0; 405 | }; 406 | 8AFA55F223A1523537B71956 /* [CP] Copy Pods Resources */ = { 407 | isa = PBXShellScriptBuildPhase; 408 | buildActionMask = 2147483647; 409 | files = ( 410 | ); 411 | inputPaths = ( 412 | ); 413 | name = "[CP] Copy Pods Resources"; 414 | outputPaths = ( 415 | ); 416 | runOnlyForDeploymentPostprocessing = 0; 417 | shellPath = /bin/sh; 418 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ApplicationGroupKitTVOS/Pods-ApplicationGroupKitTVOS-resources.sh\"\n"; 419 | showEnvVarsInLog = 0; 420 | }; 421 | 8F0742643284F9C0BEB2EF00 /* [CP] Check Pods Manifest.lock */ = { 422 | isa = PBXShellScriptBuildPhase; 423 | buildActionMask = 2147483647; 424 | files = ( 425 | ); 426 | inputPaths = ( 427 | ); 428 | name = "[CP] Check Pods Manifest.lock"; 429 | outputPaths = ( 430 | ); 431 | runOnlyForDeploymentPostprocessing = 0; 432 | shellPath = /bin/sh; 433 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 434 | showEnvVarsInLog = 0; 435 | }; 436 | 92974C7F4C16DCF9D6C3964D /* [CP] Check Pods Manifest.lock */ = { 437 | isa = PBXShellScriptBuildPhase; 438 | buildActionMask = 2147483647; 439 | files = ( 440 | ); 441 | inputPaths = ( 442 | ); 443 | name = "[CP] Check Pods Manifest.lock"; 444 | outputPaths = ( 445 | ); 446 | runOnlyForDeploymentPostprocessing = 0; 447 | shellPath = /bin/sh; 448 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 449 | showEnvVarsInLog = 0; 450 | }; 451 | EACB67B58CA7C806ABBBDF78 /* [CP] Copy Pods Resources */ = { 452 | isa = PBXShellScriptBuildPhase; 453 | buildActionMask = 2147483647; 454 | files = ( 455 | ); 456 | inputPaths = ( 457 | ); 458 | name = "[CP] Copy Pods Resources"; 459 | outputPaths = ( 460 | ); 461 | runOnlyForDeploymentPostprocessing = 0; 462 | shellPath = /bin/sh; 463 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ApplicationGroupKitOSX/Pods-ApplicationGroupKitOSX-resources.sh\"\n"; 464 | showEnvVarsInLog = 0; 465 | }; 466 | /* End PBXShellScriptBuildPhase section */ 467 | 468 | /* Begin PBXSourcesBuildPhase section */ 469 | C4CC50B31C3B36270021AA46 /* Sources */ = { 470 | isa = PBXSourcesBuildPhase; 471 | buildActionMask = 2147483647; 472 | files = ( 473 | 485AF2891E979AD900D9DF7D /* DarwinNotificationCenter.swift in Sources */, 474 | 485AF28F1E979AD900D9DF7D /* FileMessenger.swift in Sources */, 475 | 485AF2921E979AD900D9DF7D /* KeyChainMessenger.swift in Sources */, 476 | 485AF28C1E979AD900D9DF7D /* FileCoordinatorMessenger.swift in Sources */, 477 | 485AF2831E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift in Sources */, 478 | 485AF2981E979AD900D9DF7D /* MessengerType.swift in Sources */, 479 | 485AF2951E979AD900D9DF7D /* Messenger.swift in Sources */, 480 | 485AF2861E979AD900D9DF7D /* ApplicationGroup.swift in Sources */, 481 | 485AF29B1E979AD900D9DF7D /* PreferencesMessenger.swift in Sources */, 482 | 485AF29E1E979AD900D9DF7D /* UserDefaultsMessenger.swift in Sources */, 483 | ); 484 | runOnlyForDeploymentPostprocessing = 0; 485 | }; 486 | C4CC50E31C3B3E980021AA46 /* Sources */ = { 487 | isa = PBXSourcesBuildPhase; 488 | buildActionMask = 2147483647; 489 | files = ( 490 | 485AF28A1E979AD900D9DF7D /* DarwinNotificationCenter.swift in Sources */, 491 | 485AF2901E979AD900D9DF7D /* FileMessenger.swift in Sources */, 492 | 485AF2931E979AD900D9DF7D /* KeyChainMessenger.swift in Sources */, 493 | 485AF28D1E979AD900D9DF7D /* FileCoordinatorMessenger.swift in Sources */, 494 | 485AF2841E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift in Sources */, 495 | 485AF2991E979AD900D9DF7D /* MessengerType.swift in Sources */, 496 | 485AF2961E979AD900D9DF7D /* Messenger.swift in Sources */, 497 | 485AF2871E979AD900D9DF7D /* ApplicationGroup.swift in Sources */, 498 | 485AF29C1E979AD900D9DF7D /* PreferencesMessenger.swift in Sources */, 499 | 485AF29F1E979AD900D9DF7D /* UserDefaultsMessenger.swift in Sources */, 500 | ); 501 | runOnlyForDeploymentPostprocessing = 0; 502 | }; 503 | C4CC50F01C3B3EB40021AA46 /* Sources */ = { 504 | isa = PBXSourcesBuildPhase; 505 | buildActionMask = 2147483647; 506 | files = ( 507 | 485AF2881E979AD900D9DF7D /* ApplicationGroup.swift in Sources */, 508 | 485AF29A1E979AD900D9DF7D /* MessengerType.swift in Sources */, 509 | 485AF2A01E979AD900D9DF7D /* UserDefaultsMessenger.swift in Sources */, 510 | 485AF2971E979AD900D9DF7D /* Messenger.swift in Sources */, 511 | 485AF29D1E979AD900D9DF7D /* PreferencesMessenger.swift in Sources */, 512 | 485AF2911E979AD900D9DF7D /* FileMessenger.swift in Sources */, 513 | 485AF2941E979AD900D9DF7D /* KeyChainMessenger.swift in Sources */, 514 | 485AF28E1E979AD900D9DF7D /* FileCoordinatorMessenger.swift in Sources */, 515 | 485AF2851E979AD900D9DF7D /* ApplicationGroup+Prephirences.swift in Sources */, 516 | 485AF28B1E979AD900D9DF7D /* DarwinNotificationCenter.swift in Sources */, 517 | ); 518 | runOnlyForDeploymentPostprocessing = 0; 519 | }; 520 | /* End PBXSourcesBuildPhase section */ 521 | 522 | /* Begin XCBuildConfiguration section */ 523 | C4CC50BE1C3B36270021AA46 /* Debug */ = { 524 | isa = XCBuildConfiguration; 525 | buildSettings = { 526 | ALWAYS_SEARCH_USER_PATHS = NO; 527 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 528 | CLANG_CXX_LIBRARY = "libc++"; 529 | CLANG_ENABLE_MODULES = YES; 530 | CLANG_ENABLE_OBJC_ARC = YES; 531 | CLANG_WARN_BOOL_CONVERSION = YES; 532 | CLANG_WARN_CONSTANT_CONVERSION = YES; 533 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 534 | CLANG_WARN_EMPTY_BODY = YES; 535 | CLANG_WARN_ENUM_CONVERSION = YES; 536 | CLANG_WARN_INFINITE_RECURSION = YES; 537 | CLANG_WARN_INT_CONVERSION = YES; 538 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 539 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 540 | CLANG_WARN_UNREACHABLE_CODE = YES; 541 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 542 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 543 | COPY_PHASE_STRIP = NO; 544 | CURRENT_PROJECT_VERSION = 1; 545 | DEBUG_INFORMATION_FORMAT = dwarf; 546 | ENABLE_STRICT_OBJC_MSGSEND = YES; 547 | ENABLE_TESTABILITY = YES; 548 | GCC_C_LANGUAGE_STANDARD = gnu99; 549 | GCC_DYNAMIC_NO_PIC = NO; 550 | GCC_NO_COMMON_BLOCKS = YES; 551 | GCC_OPTIMIZATION_LEVEL = 0; 552 | GCC_PREPROCESSOR_DEFINITIONS = ( 553 | "DEBUG=1", 554 | "$(inherited)", 555 | ); 556 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 557 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 558 | GCC_WARN_UNDECLARED_SELECTOR = YES; 559 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 560 | GCC_WARN_UNUSED_FUNCTION = YES; 561 | GCC_WARN_UNUSED_VARIABLE = YES; 562 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 563 | MTL_ENABLE_DEBUG_INFO = YES; 564 | ONLY_ACTIVE_ARCH = YES; 565 | SDKROOT = iphoneos; 566 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 567 | TARGETED_DEVICE_FAMILY = "1,2"; 568 | VERSIONING_SYSTEM = "apple-generic"; 569 | VERSION_INFO_PREFIX = ""; 570 | }; 571 | name = Debug; 572 | }; 573 | C4CC50BF1C3B36270021AA46 /* Release */ = { 574 | isa = XCBuildConfiguration; 575 | buildSettings = { 576 | ALWAYS_SEARCH_USER_PATHS = NO; 577 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 578 | CLANG_CXX_LIBRARY = "libc++"; 579 | CLANG_ENABLE_MODULES = YES; 580 | CLANG_ENABLE_OBJC_ARC = YES; 581 | CLANG_WARN_BOOL_CONVERSION = YES; 582 | CLANG_WARN_CONSTANT_CONVERSION = YES; 583 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 584 | CLANG_WARN_EMPTY_BODY = YES; 585 | CLANG_WARN_ENUM_CONVERSION = YES; 586 | CLANG_WARN_INFINITE_RECURSION = YES; 587 | CLANG_WARN_INT_CONVERSION = YES; 588 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 589 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 590 | CLANG_WARN_UNREACHABLE_CODE = YES; 591 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 592 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 593 | COPY_PHASE_STRIP = NO; 594 | CURRENT_PROJECT_VERSION = 1; 595 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 596 | ENABLE_NS_ASSERTIONS = NO; 597 | ENABLE_STRICT_OBJC_MSGSEND = YES; 598 | GCC_C_LANGUAGE_STANDARD = gnu99; 599 | GCC_NO_COMMON_BLOCKS = YES; 600 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 601 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 602 | GCC_WARN_UNDECLARED_SELECTOR = YES; 603 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 604 | GCC_WARN_UNUSED_FUNCTION = YES; 605 | GCC_WARN_UNUSED_VARIABLE = YES; 606 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 607 | MTL_ENABLE_DEBUG_INFO = NO; 608 | SDKROOT = iphoneos; 609 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 610 | TARGETED_DEVICE_FAMILY = "1,2"; 611 | VALIDATE_PRODUCT = YES; 612 | VERSIONING_SYSTEM = "apple-generic"; 613 | VERSION_INFO_PREFIX = ""; 614 | }; 615 | name = Release; 616 | }; 617 | C4CC50C11C3B36270021AA46 /* Debug */ = { 618 | isa = XCBuildConfiguration; 619 | baseConfigurationReference = D0D8DF972A8AD6C5258AF1A8 /* Pods-ApplicationGroupKit.debug.xcconfig */; 620 | buildSettings = { 621 | CLANG_ENABLE_MODULES = YES; 622 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 623 | DEFINES_MODULE = YES; 624 | DYLIB_COMPATIBILITY_VERSION = 1; 625 | DYLIB_CURRENT_VERSION = 1; 626 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 627 | INFOPLIST_FILE = Xcode/iOS/Info.plist; 628 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 629 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 630 | PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.ApplicationGroupKit; 631 | PRODUCT_NAME = "$(TARGET_NAME)"; 632 | SKIP_INSTALL = YES; 633 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 634 | SWIFT_VERSION = 3.0; 635 | }; 636 | name = Debug; 637 | }; 638 | C4CC50C21C3B36270021AA46 /* Release */ = { 639 | isa = XCBuildConfiguration; 640 | baseConfigurationReference = 54B0214CD66ADDE960103E11 /* Pods-ApplicationGroupKit.release.xcconfig */; 641 | buildSettings = { 642 | CLANG_ENABLE_MODULES = YES; 643 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 644 | DEFINES_MODULE = YES; 645 | DYLIB_COMPATIBILITY_VERSION = 1; 646 | DYLIB_CURRENT_VERSION = 1; 647 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 648 | INFOPLIST_FILE = Xcode/iOS/Info.plist; 649 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 650 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 651 | PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.ApplicationGroupKit; 652 | PRODUCT_NAME = "$(TARGET_NAME)"; 653 | SKIP_INSTALL = YES; 654 | SWIFT_VERSION = 3.0; 655 | }; 656 | name = Release; 657 | }; 658 | C4CC50EE1C3B3E980021AA46 /* Debug */ = { 659 | isa = XCBuildConfiguration; 660 | baseConfigurationReference = 6717F1D200BC8E6C77704AB1 /* Pods-ApplicationGroupKitOSX.debug.xcconfig */; 661 | buildSettings = { 662 | CLANG_ENABLE_MODULES = YES; 663 | CODE_SIGN_IDENTITY = "-"; 664 | COMBINE_HIDPI_IMAGES = YES; 665 | DEFINES_MODULE = YES; 666 | DYLIB_COMPATIBILITY_VERSION = 1; 667 | DYLIB_CURRENT_VERSION = 1; 668 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 669 | FRAMEWORK_VERSION = A; 670 | INFOPLIST_FILE = Xcode/macOS/Info.plist; 671 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 672 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 673 | MACOSX_DEPLOYMENT_TARGET = 10.11; 674 | PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.ApplicationGroupKit; 675 | PRODUCT_NAME = ApplicationGroupKit; 676 | SDKROOT = macosx; 677 | SKIP_INSTALL = YES; 678 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 679 | SWIFT_VERSION = 3.0; 680 | }; 681 | name = Debug; 682 | }; 683 | C4CC50EF1C3B3E980021AA46 /* Release */ = { 684 | isa = XCBuildConfiguration; 685 | baseConfigurationReference = 4AD07F29FA0A339A2B0E1A92 /* Pods-ApplicationGroupKitOSX.release.xcconfig */; 686 | buildSettings = { 687 | CLANG_ENABLE_MODULES = YES; 688 | CODE_SIGN_IDENTITY = "-"; 689 | COMBINE_HIDPI_IMAGES = YES; 690 | DEFINES_MODULE = YES; 691 | DYLIB_COMPATIBILITY_VERSION = 1; 692 | DYLIB_CURRENT_VERSION = 1; 693 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 694 | FRAMEWORK_VERSION = A; 695 | INFOPLIST_FILE = Xcode/macOS/Info.plist; 696 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 697 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 698 | MACOSX_DEPLOYMENT_TARGET = 10.11; 699 | PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.ApplicationGroupKit; 700 | PRODUCT_NAME = ApplicationGroupKit; 701 | SDKROOT = macosx; 702 | SKIP_INSTALL = YES; 703 | SWIFT_VERSION = 3.0; 704 | }; 705 | name = Release; 706 | }; 707 | C4CC50FB1C3B3EB40021AA46 /* Debug */ = { 708 | isa = XCBuildConfiguration; 709 | baseConfigurationReference = E7BA5924E99AE4AE121F42F8 /* Pods-ApplicationGroupKitTVOS.debug.xcconfig */; 710 | buildSettings = { 711 | CLANG_ENABLE_MODULES = YES; 712 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 713 | DEFINES_MODULE = YES; 714 | DYLIB_COMPATIBILITY_VERSION = 1; 715 | DYLIB_CURRENT_VERSION = 1; 716 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 717 | INFOPLIST_FILE = Xcode/tvOS/Info.plist; 718 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 719 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 720 | PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.ApplicationGroupKitTVOS; 721 | PRODUCT_NAME = ApplicationGroupKit; 722 | SDKROOT = appletvos; 723 | SKIP_INSTALL = YES; 724 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 725 | SWIFT_VERSION = 3.0; 726 | TARGETED_DEVICE_FAMILY = 3; 727 | TVOS_DEPLOYMENT_TARGET = 9.1; 728 | }; 729 | name = Debug; 730 | }; 731 | C4CC50FC1C3B3EB40021AA46 /* Release */ = { 732 | isa = XCBuildConfiguration; 733 | baseConfigurationReference = 67893A42D2BAFC718E333E69 /* Pods-ApplicationGroupKitTVOS.release.xcconfig */; 734 | buildSettings = { 735 | CLANG_ENABLE_MODULES = YES; 736 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 737 | DEFINES_MODULE = YES; 738 | DYLIB_COMPATIBILITY_VERSION = 1; 739 | DYLIB_CURRENT_VERSION = 1; 740 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 741 | INFOPLIST_FILE = Xcode/tvOS/Info.plist; 742 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 743 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 744 | PRODUCT_BUNDLE_IDENTIFIER = fr.phimage.ApplicationGroupKitTVOS; 745 | PRODUCT_NAME = ApplicationGroupKit; 746 | SDKROOT = appletvos; 747 | SKIP_INSTALL = YES; 748 | SWIFT_VERSION = 3.0; 749 | TARGETED_DEVICE_FAMILY = 3; 750 | TVOS_DEPLOYMENT_TARGET = 9.1; 751 | }; 752 | name = Release; 753 | }; 754 | /* End XCBuildConfiguration section */ 755 | 756 | /* Begin XCConfigurationList section */ 757 | C4CC50B21C3B36270021AA46 /* Build configuration list for PBXProject "ApplicationGroupKit" */ = { 758 | isa = XCConfigurationList; 759 | buildConfigurations = ( 760 | C4CC50BE1C3B36270021AA46 /* Debug */, 761 | C4CC50BF1C3B36270021AA46 /* Release */, 762 | ); 763 | defaultConfigurationIsVisible = 0; 764 | defaultConfigurationName = Release; 765 | }; 766 | C4CC50C01C3B36270021AA46 /* Build configuration list for PBXNativeTarget "ApplicationGroupKit" */ = { 767 | isa = XCConfigurationList; 768 | buildConfigurations = ( 769 | C4CC50C11C3B36270021AA46 /* Debug */, 770 | C4CC50C21C3B36270021AA46 /* Release */, 771 | ); 772 | defaultConfigurationIsVisible = 0; 773 | defaultConfigurationName = Release; 774 | }; 775 | C4CC50ED1C3B3E980021AA46 /* Build configuration list for PBXNativeTarget "ApplicationGroupKitOSX" */ = { 776 | isa = XCConfigurationList; 777 | buildConfigurations = ( 778 | C4CC50EE1C3B3E980021AA46 /* Debug */, 779 | C4CC50EF1C3B3E980021AA46 /* Release */, 780 | ); 781 | defaultConfigurationIsVisible = 0; 782 | defaultConfigurationName = Release; 783 | }; 784 | C4CC50FA1C3B3EB40021AA46 /* Build configuration list for PBXNativeTarget "ApplicationGroupKitTVOS" */ = { 785 | isa = XCConfigurationList; 786 | buildConfigurations = ( 787 | C4CC50FB1C3B3EB40021AA46 /* Debug */, 788 | C4CC50FC1C3B3EB40021AA46 /* Release */, 789 | ); 790 | defaultConfigurationIsVisible = 0; 791 | defaultConfigurationName = Release; 792 | }; 793 | /* End XCConfigurationList section */ 794 | }; 795 | rootObject = C4CC50AF1C3B36270021AA46 /* Project object */; 796 | } 797 | --------------------------------------------------------------------------------