├── GCDMulticastDelegate.xcodeproj
├── xcuserdata
│ └── Hossein.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── GCDMulticastDelegate.xcscheme
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── Hossein.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── project.pbxproj
├── GCDMulticastDelegate
├── GCDMulticastDelegate.h
├── Info.plist
└── GCDMulticastDelegate.swift
├── GCDMulticastDelegateTests
├── Info.plist
└── GCDMulticastDelegateTests.swift
├── LICENSE
└── README.md
/GCDMulticastDelegate.xcodeproj/xcuserdata/Hossein.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/GCDMulticastDelegate.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GCDMulticastDelegate.xcodeproj/project.xcworkspace/xcuserdata/Hossein.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hossein1448/GCDMulticastDelegate/HEAD/GCDMulticastDelegate.xcodeproj/project.xcworkspace/xcuserdata/Hossein.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/GCDMulticastDelegate/GCDMulticastDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // GCDMulticastDelegate.h
3 | // GCDMulticastDelegate
4 | //
5 | // Created by Hossein Asgari on 2/24/17.
6 | // Copyright © 2017 Hossein Asgari. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for GCDMulticastDelegate.
12 | FOUNDATION_EXPORT double GCDMulticastDelegateVersionNumber;
13 |
14 | //! Project version string for GCDMulticastDelegate.
15 | FOUNDATION_EXPORT const unsigned char GCDMulticastDelegateVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/GCDMulticastDelegate.xcodeproj/xcuserdata/Hossein.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | GCDMulticastDelegate.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 9466EB161E600F6C00AE38D9
16 |
17 | primary
18 |
19 |
20 | 9466EB1F1E600F6C00AE38D9
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/GCDMulticastDelegateTests/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 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GCDMulticastDelegate/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 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Hossein Asgari
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GCDMulticastDelegate
2 |
3 | GCDMulticastDelegate is simple class that provides multicast/one-to-many delegation with proper support for GCD queues.
4 | * It provides a means for managing a list of delegates.
5 | * This class also provides proper support for GCD queues.So each delegate specifies which queue they would like their delegate invocations to be dispatched onto.
6 | * All delegate dispatching is done asynchronously. It also uses weak refrences for keep delegates to avoid [Memory Leak](https://en.wikipedia.org/wiki/Memory_leak).
7 | * It's completely thread-safe
8 |
9 | For More Information You can refer to [Observer Pattern](https://en.wikipedia.org/wiki/Observer_pattern)
10 |
11 | Installation
12 | ============
13 | Simply just add `GCDMulticastDelegate.swift` to your project
14 |
15 | ## Requirements
16 |
17 | - iOS 8.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+
18 | - Xcode 8.1+
19 | - Swift 3.0+
20 |
21 | Usage
22 | ============
23 | 1. Add to your class: `let gcdMulticastDelegate = GCDMulticastDelegate()`
24 | 2. implement `addDelegate(deleg delegate:AnyObject, dispatch_queue queue:DispatchQueue)` in your class
25 | 3. Other classes must be added as a delegate: `serviceProvide.addDelegate(deleg: self, dispatch_queue: DispatchQueue.main)`
26 | 4. When you need to notify your delegates: `multicastDelegate.invoke {$0.someEvent()}`
27 |
28 | ###Example
29 | ```swift
30 | protocol FirstServiceProviderDelegate: class {
31 | func onSomeEvent()
32 | }
33 |
34 | class FirstServiceProvider: NSObject {
35 |
36 | let multicastDelegate:GCDMulticastDelegate = GCDMulticastDelegate()
37 |
38 | func testSomeEvent() {
39 |
40 | self.multicastDelegate.invoke {
41 | $0.onSomeEvent()
42 | }
43 | }
44 |
45 | public func addDelegate(deleg delegate:AnyObject, dispatch_queue queue:DispatchQueue){
46 |
47 | multicastDelegate.addDelegate(deleg: delegate as! FirstServiceProviderDelegate, queue: queue)
48 | }
49 |
50 | public func removeDelegate(deleg delegate:AnyObject, dispatch queue:DispatchQueue) {
51 |
52 | multicastDelegate.removeDelegate(deleg: delegate, queue: queue)
53 | }
54 | }
55 | ```
56 | ```swift
57 | class ViewController: UIViewController , FirstServiceProviderDelegate{
58 |
59 | override func viewDidLoad() {
60 | super.viewDidLoad()
61 | // Do any additional setup after loading the view, typically from a nib.
62 |
63 | let service = FirstServiceProvider()
64 | service.addDelegate(deleg: self, dispatch_queue: DispatchQueue.main)
65 | }
66 |
67 | func onSomeEvent() {
68 |
69 | print("Some Event Delegate was called")
70 | }
71 | }
72 | ```
73 | use this if You prefer specific GCD queue:
74 | ```swift
75 | let service = FirstServiceProvider()
76 | let myQueue = DispatchQueue(label: "com.example.my-serial-queue")
77 |
78 | service.addDelegate(deleg: self, dispatch_queue: myQueue)
79 | ```
80 | also Use `removeDelegate` for removing a class from delegates list
81 |
82 | You will find a sample usage of GCDMulticastDelegate in `GCDMulticastDelegateTests.swift`
83 |
--------------------------------------------------------------------------------
/GCDMulticastDelegate.xcodeproj/xcuserdata/Hossein.xcuserdatad/xcschemes/GCDMulticastDelegate.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/GCDMulticastDelegate/GCDMulticastDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDMulticastDelegate.swift
3 | // GCDMulticastDelegate
4 | //
5 | // Created by Hossein Asgari on 2/24/17.
6 | // Copyright © 2017 Hossein Asgari. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class GCDMulticastDelegateNode {
12 |
13 | weak var delegate:AnyObject!
14 | var delegateQueue:DispatchQueue!
15 |
16 | init(delegate del:AnyObject! ,delegateQueue queue:DispatchQueue!) {
17 |
18 | delegate = del
19 | delegateQueue = queue
20 | }
21 | }
22 |
23 |
24 |
25 | class GCDMulticastDelegate {
26 |
27 | private var delegateNodes = [GCDMulticastDelegateNode]()
28 |
29 | public func addDelegate(deleg delegate:AnyObject! ,queue delegateQueue:DispatchQueue!) {
30 |
31 | if delegate == nil {
32 | return
33 | }
34 |
35 | if delegateQueue == nil {
36 | return
37 | }
38 |
39 | let node = GCDMulticastDelegateNode(delegate: delegate, delegateQueue: delegateQueue)
40 |
41 | self.synchronized(lockObj: delegateNodes as AnyObject!, closure: {
42 |
43 | delegateNodes.append(node)
44 | })
45 | }
46 |
47 | public func removeDelegate(deleg delegate:AnyObject! ,queue delegateQueue:DispatchQueue!) {
48 |
49 | if delegate == nil {
50 | return
51 | }
52 |
53 | self.synchronized(lockObj: delegateNodes as AnyObject!, closure: {
54 |
55 | for i in (0.. Int {
96 |
97 | return delegateNodes.count;
98 | }
99 |
100 | public func countOfClass(class cl:AnyClass) -> Int{
101 |
102 | var count:Int = 0
103 | for nodeDelegate in delegateNodes {
104 |
105 | if nodeDelegate.delegate.isKind(of: cl) {
106 | count += 1
107 | }
108 | }
109 |
110 | return count;
111 | }
112 |
113 | public func countOfSelector(selector sel:Selector) -> Int{
114 |
115 | var count:Int = 0
116 | for nodeDelegate in delegateNodes {
117 |
118 | if nodeDelegate.delegate.responds(to: sel) {
119 | count += 1
120 | }
121 | }
122 |
123 | return count;
124 | }
125 |
126 | public func invoke(_ invocation: @escaping (T) -> ()) {
127 |
128 |
129 | for i in (0..Void)
154 | {
155 | objc_sync_enter(lockObj)
156 | closure()
157 | objc_sync_exit(lockObj)
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/GCDMulticastDelegateTests/GCDMulticastDelegateTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDMulticastDelegateTests.swift
3 | // GCDMulticastDelegateTests
4 | //
5 | // Created by Hossein Asgari on 2/24/17.
6 | // Copyright © 2017 Hossein Asgari. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | protocol FirstServiceProviderDelegate: class {
12 |
13 | func onSomeEvent()
14 | func onSomeEventWithValue(value:Int)
15 |
16 | }
17 |
18 | class FirstServiceProvider: NSObject {
19 |
20 | let multicastDelegate:GCDMulticastDelegate = GCDMulticastDelegate()
21 |
22 | func testSomeEvent() {
23 |
24 | self.multicastDelegate.invoke {
25 | $0.onSomeEvent()
26 | }
27 | }
28 |
29 | func testSomeEventWithValue() {
30 |
31 | self.multicastDelegate.invoke {
32 | $0.onSomeEventWithValue(value: 1448)
33 | }
34 | }
35 |
36 | public func addDelegate(deleg delegate:AnyObject, dispatch_queue queue:DispatchQueue){
37 |
38 | multicastDelegate.addDelegate(deleg: delegate as! FirstServiceProviderDelegate, queue: queue)
39 | }
40 |
41 | public func removeDelegate(deleg delegate:AnyObject, dispatch queue:DispatchQueue) {
42 |
43 | multicastDelegate.removeDelegate(deleg: delegate, queue: queue)
44 | }
45 | }
46 |
47 | protocol SecondServiceProviderDelegate: class {
48 |
49 | func onSomeEventGCD()
50 | }
51 |
52 | class SecondServiceProvider: NSObject {
53 |
54 | let multicastDelegate:GCDMulticastDelegate = GCDMulticastDelegate()
55 |
56 | func testSomeEventGCD() {
57 |
58 | self.multicastDelegate.invoke {
59 | $0.onSomeEventGCD()
60 | }
61 | }
62 |
63 | public func addDelegate(deleg delegate:AnyObject, dispatch_queue queue:DispatchQueue){
64 |
65 | multicastDelegate.addDelegate(deleg: delegate as! SecondServiceProviderDelegate, queue: queue)
66 | }
67 |
68 | public func removeDelegate(deleg delegate:AnyObject, dispatch queue:DispatchQueue) {
69 |
70 | multicastDelegate.removeDelegate(deleg: delegate, queue: queue)
71 | }
72 | }
73 |
74 |
75 | @testable import GCDMulticastDelegate
76 |
77 | class GCDMulticastDelegateTests: XCTestCase , FirstServiceProviderDelegate , SecondServiceProviderDelegate{
78 |
79 | override func setUp() {
80 | super.setUp()
81 | // Put setup code here. This method is called before the invocation of each test method in the class.
82 | }
83 |
84 | override func tearDown() {
85 | // Put teardown code here. This method is called after the invocation of each test method in the class.
86 | super.tearDown()
87 | }
88 |
89 | func testDelegateUsage() {
90 | // This is an example of a functional test case.
91 | // Use XCTAssert and related functions to verify your tests produce the correct results.
92 |
93 | let serviceProvide:FirstServiceProvider = FirstServiceProvider()
94 | serviceProvide.addDelegate(deleg: self, dispatch_queue: DispatchQueue.main)
95 |
96 | serviceProvide.testSomeEvent()
97 | serviceProvide.testSomeEventWithValue()
98 |
99 | let exp = self.expectation(description: "wait for finish unSyncCall")
100 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
101 |
102 | exp.fulfill()
103 | }
104 |
105 | self.waitForExpectations(timeout: 40, handler: nil)
106 |
107 | }
108 |
109 | func testDelegateGCDUsage() {
110 | // This is an example of a functional test case.
111 | // Use XCTAssert and related functions to verify your tests produce the correct results.
112 |
113 | let serviceProvide:SecondServiceProvider = SecondServiceProvider()
114 | let testQueue = DispatchQueue(label: "com.test.gcd-multicast-delegae-queue")
115 | serviceProvide.addDelegate(deleg: self, dispatch_queue: testQueue)
116 |
117 | serviceProvide.testSomeEventGCD()
118 |
119 | let exp = self.expectation(description: "wait for finish unSyncCall in GCD")
120 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
121 |
122 | exp.fulfill()
123 | }
124 |
125 | self.waitForExpectations(timeout: 40, handler: nil)
126 |
127 | }
128 |
129 | func currentQueueName() -> String? {
130 | let name = __dispatch_queue_get_label(nil)
131 | return String(cString: name, encoding: .utf8)
132 | }
133 |
134 | // MARK: FirstServiceProviderDelegate
135 | func onSomeEvent(){
136 |
137 | XCTAssertTrue(Thread.isMainThread)
138 |
139 | }
140 | func onSomeEventWithValue(value:Int){
141 |
142 | XCTAssertEqual(value, 1448)
143 | XCTAssertTrue(Thread.isMainThread)
144 | }
145 |
146 | // MARK: SecondServiceProviderDelegate
147 | func onSomeEventGCD() {
148 |
149 | XCTAssertFalse(Thread.isMainThread)
150 | XCTAssertEqual(self.currentQueueName(), "com.test.gcd-multicast-delegae-queue")
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/GCDMulticastDelegate.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 94392EA61E6214EA00A41F5D /* GCDMulticastDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9466EB311E60110000AE38D9 /* GCDMulticastDelegate.swift */; };
11 | 9466EB211E600F6C00AE38D9 /* GCDMulticastDelegate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9466EB171E600F6C00AE38D9 /* GCDMulticastDelegate.framework */; };
12 | 9466EB261E600F6C00AE38D9 /* GCDMulticastDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9466EB251E600F6C00AE38D9 /* GCDMulticastDelegateTests.swift */; };
13 | 9466EB281E600F6C00AE38D9 /* GCDMulticastDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9466EB1A1E600F6C00AE38D9 /* GCDMulticastDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
14 | 9466EB321E60110000AE38D9 /* GCDMulticastDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9466EB311E60110000AE38D9 /* GCDMulticastDelegate.swift */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXContainerItemProxy section */
18 | 9466EB221E600F6C00AE38D9 /* PBXContainerItemProxy */ = {
19 | isa = PBXContainerItemProxy;
20 | containerPortal = 9466EB0E1E600F6C00AE38D9 /* Project object */;
21 | proxyType = 1;
22 | remoteGlobalIDString = 9466EB161E600F6C00AE38D9;
23 | remoteInfo = GCDMulticastDelegate;
24 | };
25 | /* End PBXContainerItemProxy section */
26 |
27 | /* Begin PBXFileReference section */
28 | 9466EB171E600F6C00AE38D9 /* GCDMulticastDelegate.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GCDMulticastDelegate.framework; sourceTree = BUILT_PRODUCTS_DIR; };
29 | 9466EB1A1E600F6C00AE38D9 /* GCDMulticastDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GCDMulticastDelegate.h; sourceTree = ""; };
30 | 9466EB1B1E600F6C00AE38D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 9466EB201E600F6C00AE38D9 /* GCDMulticastDelegateTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GCDMulticastDelegateTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
32 | 9466EB251E600F6C00AE38D9 /* GCDMulticastDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GCDMulticastDelegateTests.swift; sourceTree = ""; };
33 | 9466EB271E600F6C00AE38D9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
34 | 9466EB311E60110000AE38D9 /* GCDMulticastDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GCDMulticastDelegate.swift; sourceTree = ""; };
35 | /* End PBXFileReference section */
36 |
37 | /* Begin PBXFrameworksBuildPhase section */
38 | 9466EB131E600F6C00AE38D9 /* Frameworks */ = {
39 | isa = PBXFrameworksBuildPhase;
40 | buildActionMask = 2147483647;
41 | files = (
42 | );
43 | runOnlyForDeploymentPostprocessing = 0;
44 | };
45 | 9466EB1D1E600F6C00AE38D9 /* Frameworks */ = {
46 | isa = PBXFrameworksBuildPhase;
47 | buildActionMask = 2147483647;
48 | files = (
49 | 9466EB211E600F6C00AE38D9 /* GCDMulticastDelegate.framework in Frameworks */,
50 | );
51 | runOnlyForDeploymentPostprocessing = 0;
52 | };
53 | /* End PBXFrameworksBuildPhase section */
54 |
55 | /* Begin PBXGroup section */
56 | 9466EB0D1E600F6C00AE38D9 = {
57 | isa = PBXGroup;
58 | children = (
59 | 9466EB191E600F6C00AE38D9 /* GCDMulticastDelegate */,
60 | 9466EB241E600F6C00AE38D9 /* GCDMulticastDelegateTests */,
61 | 9466EB181E600F6C00AE38D9 /* Products */,
62 | );
63 | sourceTree = "";
64 | };
65 | 9466EB181E600F6C00AE38D9 /* Products */ = {
66 | isa = PBXGroup;
67 | children = (
68 | 9466EB171E600F6C00AE38D9 /* GCDMulticastDelegate.framework */,
69 | 9466EB201E600F6C00AE38D9 /* GCDMulticastDelegateTests.xctest */,
70 | );
71 | name = Products;
72 | sourceTree = "";
73 | };
74 | 9466EB191E600F6C00AE38D9 /* GCDMulticastDelegate */ = {
75 | isa = PBXGroup;
76 | children = (
77 | 9466EB1A1E600F6C00AE38D9 /* GCDMulticastDelegate.h */,
78 | 9466EB311E60110000AE38D9 /* GCDMulticastDelegate.swift */,
79 | 9466EB1B1E600F6C00AE38D9 /* Info.plist */,
80 | );
81 | path = GCDMulticastDelegate;
82 | sourceTree = "";
83 | };
84 | 9466EB241E600F6C00AE38D9 /* GCDMulticastDelegateTests */ = {
85 | isa = PBXGroup;
86 | children = (
87 | 9466EB251E600F6C00AE38D9 /* GCDMulticastDelegateTests.swift */,
88 | 9466EB271E600F6C00AE38D9 /* Info.plist */,
89 | );
90 | path = GCDMulticastDelegateTests;
91 | sourceTree = "";
92 | };
93 | /* End PBXGroup section */
94 |
95 | /* Begin PBXHeadersBuildPhase section */
96 | 9466EB141E600F6C00AE38D9 /* Headers */ = {
97 | isa = PBXHeadersBuildPhase;
98 | buildActionMask = 2147483647;
99 | files = (
100 | 9466EB281E600F6C00AE38D9 /* GCDMulticastDelegate.h in Headers */,
101 | );
102 | runOnlyForDeploymentPostprocessing = 0;
103 | };
104 | /* End PBXHeadersBuildPhase section */
105 |
106 | /* Begin PBXNativeTarget section */
107 | 9466EB161E600F6C00AE38D9 /* GCDMulticastDelegate */ = {
108 | isa = PBXNativeTarget;
109 | buildConfigurationList = 9466EB2B1E600F6C00AE38D9 /* Build configuration list for PBXNativeTarget "GCDMulticastDelegate" */;
110 | buildPhases = (
111 | 9466EB121E600F6C00AE38D9 /* Sources */,
112 | 9466EB131E600F6C00AE38D9 /* Frameworks */,
113 | 9466EB141E600F6C00AE38D9 /* Headers */,
114 | 9466EB151E600F6C00AE38D9 /* Resources */,
115 | );
116 | buildRules = (
117 | );
118 | dependencies = (
119 | );
120 | name = GCDMulticastDelegate;
121 | productName = GCDMulticastDelegate;
122 | productReference = 9466EB171E600F6C00AE38D9 /* GCDMulticastDelegate.framework */;
123 | productType = "com.apple.product-type.framework";
124 | };
125 | 9466EB1F1E600F6C00AE38D9 /* GCDMulticastDelegateTests */ = {
126 | isa = PBXNativeTarget;
127 | buildConfigurationList = 9466EB2E1E600F6C00AE38D9 /* Build configuration list for PBXNativeTarget "GCDMulticastDelegateTests" */;
128 | buildPhases = (
129 | 9466EB1C1E600F6C00AE38D9 /* Sources */,
130 | 9466EB1D1E600F6C00AE38D9 /* Frameworks */,
131 | 9466EB1E1E600F6C00AE38D9 /* Resources */,
132 | );
133 | buildRules = (
134 | );
135 | dependencies = (
136 | 9466EB231E600F6C00AE38D9 /* PBXTargetDependency */,
137 | );
138 | name = GCDMulticastDelegateTests;
139 | productName = GCDMulticastDelegateTests;
140 | productReference = 9466EB201E600F6C00AE38D9 /* GCDMulticastDelegateTests.xctest */;
141 | productType = "com.apple.product-type.bundle.unit-test";
142 | };
143 | /* End PBXNativeTarget section */
144 |
145 | /* Begin PBXProject section */
146 | 9466EB0E1E600F6C00AE38D9 /* Project object */ = {
147 | isa = PBXProject;
148 | attributes = {
149 | LastSwiftUpdateCheck = 0820;
150 | LastUpgradeCheck = 0820;
151 | ORGANIZATIONNAME = "Hossein Asgari";
152 | TargetAttributes = {
153 | 9466EB161E600F6C00AE38D9 = {
154 | CreatedOnToolsVersion = 8.2;
155 | DevelopmentTeam = 59F6BPBT28;
156 | LastSwiftMigration = 0820;
157 | ProvisioningStyle = Automatic;
158 | };
159 | 9466EB1F1E600F6C00AE38D9 = {
160 | CreatedOnToolsVersion = 8.2;
161 | DevelopmentTeam = 59F6BPBT28;
162 | ProvisioningStyle = Automatic;
163 | };
164 | };
165 | };
166 | buildConfigurationList = 9466EB111E600F6C00AE38D9 /* Build configuration list for PBXProject "GCDMulticastDelegate" */;
167 | compatibilityVersion = "Xcode 3.2";
168 | developmentRegion = English;
169 | hasScannedForEncodings = 0;
170 | knownRegions = (
171 | en,
172 | );
173 | mainGroup = 9466EB0D1E600F6C00AE38D9;
174 | productRefGroup = 9466EB181E600F6C00AE38D9 /* Products */;
175 | projectDirPath = "";
176 | projectRoot = "";
177 | targets = (
178 | 9466EB161E600F6C00AE38D9 /* GCDMulticastDelegate */,
179 | 9466EB1F1E600F6C00AE38D9 /* GCDMulticastDelegateTests */,
180 | );
181 | };
182 | /* End PBXProject section */
183 |
184 | /* Begin PBXResourcesBuildPhase section */
185 | 9466EB151E600F6C00AE38D9 /* Resources */ = {
186 | isa = PBXResourcesBuildPhase;
187 | buildActionMask = 2147483647;
188 | files = (
189 | );
190 | runOnlyForDeploymentPostprocessing = 0;
191 | };
192 | 9466EB1E1E600F6C00AE38D9 /* Resources */ = {
193 | isa = PBXResourcesBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | );
197 | runOnlyForDeploymentPostprocessing = 0;
198 | };
199 | /* End PBXResourcesBuildPhase section */
200 |
201 | /* Begin PBXSourcesBuildPhase section */
202 | 9466EB121E600F6C00AE38D9 /* Sources */ = {
203 | isa = PBXSourcesBuildPhase;
204 | buildActionMask = 2147483647;
205 | files = (
206 | 9466EB321E60110000AE38D9 /* GCDMulticastDelegate.swift in Sources */,
207 | );
208 | runOnlyForDeploymentPostprocessing = 0;
209 | };
210 | 9466EB1C1E600F6C00AE38D9 /* Sources */ = {
211 | isa = PBXSourcesBuildPhase;
212 | buildActionMask = 2147483647;
213 | files = (
214 | 94392EA61E6214EA00A41F5D /* GCDMulticastDelegate.swift in Sources */,
215 | 9466EB261E600F6C00AE38D9 /* GCDMulticastDelegateTests.swift in Sources */,
216 | );
217 | runOnlyForDeploymentPostprocessing = 0;
218 | };
219 | /* End PBXSourcesBuildPhase section */
220 |
221 | /* Begin PBXTargetDependency section */
222 | 9466EB231E600F6C00AE38D9 /* PBXTargetDependency */ = {
223 | isa = PBXTargetDependency;
224 | target = 9466EB161E600F6C00AE38D9 /* GCDMulticastDelegate */;
225 | targetProxy = 9466EB221E600F6C00AE38D9 /* PBXContainerItemProxy */;
226 | };
227 | /* End PBXTargetDependency section */
228 |
229 | /* Begin XCBuildConfiguration section */
230 | 9466EB291E600F6C00AE38D9 /* Debug */ = {
231 | isa = XCBuildConfiguration;
232 | buildSettings = {
233 | ALWAYS_SEARCH_USER_PATHS = NO;
234 | CLANG_ANALYZER_NONNULL = YES;
235 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
236 | CLANG_CXX_LIBRARY = "libc++";
237 | CLANG_ENABLE_MODULES = YES;
238 | CLANG_ENABLE_OBJC_ARC = YES;
239 | CLANG_WARN_BOOL_CONVERSION = YES;
240 | CLANG_WARN_CONSTANT_CONVERSION = YES;
241 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
242 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
243 | CLANG_WARN_EMPTY_BODY = YES;
244 | CLANG_WARN_ENUM_CONVERSION = YES;
245 | CLANG_WARN_INFINITE_RECURSION = YES;
246 | CLANG_WARN_INT_CONVERSION = YES;
247 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
248 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
249 | CLANG_WARN_UNREACHABLE_CODE = YES;
250 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
251 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
252 | COPY_PHASE_STRIP = NO;
253 | CURRENT_PROJECT_VERSION = 1;
254 | DEBUG_INFORMATION_FORMAT = dwarf;
255 | ENABLE_STRICT_OBJC_MSGSEND = YES;
256 | ENABLE_TESTABILITY = YES;
257 | GCC_C_LANGUAGE_STANDARD = gnu99;
258 | GCC_DYNAMIC_NO_PIC = NO;
259 | GCC_NO_COMMON_BLOCKS = YES;
260 | GCC_OPTIMIZATION_LEVEL = 0;
261 | GCC_PREPROCESSOR_DEFINITIONS = (
262 | "DEBUG=1",
263 | "$(inherited)",
264 | );
265 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
266 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
267 | GCC_WARN_UNDECLARED_SELECTOR = YES;
268 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
269 | GCC_WARN_UNUSED_FUNCTION = YES;
270 | GCC_WARN_UNUSED_VARIABLE = YES;
271 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
272 | MTL_ENABLE_DEBUG_INFO = YES;
273 | ONLY_ACTIVE_ARCH = YES;
274 | SDKROOT = iphoneos;
275 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
276 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
277 | TARGETED_DEVICE_FAMILY = "1,2";
278 | VERSIONING_SYSTEM = "apple-generic";
279 | VERSION_INFO_PREFIX = "";
280 | };
281 | name = Debug;
282 | };
283 | 9466EB2A1E600F6C00AE38D9 /* Release */ = {
284 | isa = XCBuildConfiguration;
285 | buildSettings = {
286 | ALWAYS_SEARCH_USER_PATHS = NO;
287 | CLANG_ANALYZER_NONNULL = YES;
288 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
289 | CLANG_CXX_LIBRARY = "libc++";
290 | CLANG_ENABLE_MODULES = YES;
291 | CLANG_ENABLE_OBJC_ARC = YES;
292 | CLANG_WARN_BOOL_CONVERSION = YES;
293 | CLANG_WARN_CONSTANT_CONVERSION = YES;
294 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
295 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
296 | CLANG_WARN_EMPTY_BODY = YES;
297 | CLANG_WARN_ENUM_CONVERSION = YES;
298 | CLANG_WARN_INFINITE_RECURSION = YES;
299 | CLANG_WARN_INT_CONVERSION = YES;
300 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
301 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
302 | CLANG_WARN_UNREACHABLE_CODE = YES;
303 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
304 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
305 | COPY_PHASE_STRIP = NO;
306 | CURRENT_PROJECT_VERSION = 1;
307 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
308 | ENABLE_NS_ASSERTIONS = NO;
309 | ENABLE_STRICT_OBJC_MSGSEND = YES;
310 | GCC_C_LANGUAGE_STANDARD = gnu99;
311 | GCC_NO_COMMON_BLOCKS = YES;
312 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
313 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
314 | GCC_WARN_UNDECLARED_SELECTOR = YES;
315 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
316 | GCC_WARN_UNUSED_FUNCTION = YES;
317 | GCC_WARN_UNUSED_VARIABLE = YES;
318 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
319 | MTL_ENABLE_DEBUG_INFO = NO;
320 | SDKROOT = iphoneos;
321 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
322 | TARGETED_DEVICE_FAMILY = "1,2";
323 | VALIDATE_PRODUCT = YES;
324 | VERSIONING_SYSTEM = "apple-generic";
325 | VERSION_INFO_PREFIX = "";
326 | };
327 | name = Release;
328 | };
329 | 9466EB2C1E600F6C00AE38D9 /* Debug */ = {
330 | isa = XCBuildConfiguration;
331 | buildSettings = {
332 | CLANG_ENABLE_MODULES = YES;
333 | CODE_SIGN_IDENTITY = "";
334 | DEFINES_MODULE = YES;
335 | DEVELOPMENT_TEAM = 59F6BPBT28;
336 | DYLIB_COMPATIBILITY_VERSION = 1;
337 | DYLIB_CURRENT_VERSION = 1;
338 | DYLIB_INSTALL_NAME_BASE = "@rpath";
339 | INFOPLIST_FILE = GCDMulticastDelegate/Info.plist;
340 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
341 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
342 | PRODUCT_BUNDLE_IDENTIFIER = com.1448.GCDMulticastDelegate;
343 | PRODUCT_NAME = "$(TARGET_NAME)";
344 | SKIP_INSTALL = YES;
345 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
346 | SWIFT_VERSION = 3.0;
347 | };
348 | name = Debug;
349 | };
350 | 9466EB2D1E600F6C00AE38D9 /* Release */ = {
351 | isa = XCBuildConfiguration;
352 | buildSettings = {
353 | CLANG_ENABLE_MODULES = YES;
354 | CODE_SIGN_IDENTITY = "";
355 | DEFINES_MODULE = YES;
356 | DEVELOPMENT_TEAM = 59F6BPBT28;
357 | DYLIB_COMPATIBILITY_VERSION = 1;
358 | DYLIB_CURRENT_VERSION = 1;
359 | DYLIB_INSTALL_NAME_BASE = "@rpath";
360 | INFOPLIST_FILE = GCDMulticastDelegate/Info.plist;
361 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
362 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
363 | PRODUCT_BUNDLE_IDENTIFIER = com.1448.GCDMulticastDelegate;
364 | PRODUCT_NAME = "$(TARGET_NAME)";
365 | SKIP_INSTALL = YES;
366 | SWIFT_VERSION = 3.0;
367 | };
368 | name = Release;
369 | };
370 | 9466EB2F1E600F6C00AE38D9 /* Debug */ = {
371 | isa = XCBuildConfiguration;
372 | buildSettings = {
373 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
374 | DEVELOPMENT_TEAM = 59F6BPBT28;
375 | INFOPLIST_FILE = GCDMulticastDelegateTests/Info.plist;
376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
377 | PRODUCT_BUNDLE_IDENTIFIER = com.1448.GCDMulticastDelegateTests;
378 | PRODUCT_NAME = "$(TARGET_NAME)";
379 | SWIFT_VERSION = 3.0;
380 | };
381 | name = Debug;
382 | };
383 | 9466EB301E600F6C00AE38D9 /* Release */ = {
384 | isa = XCBuildConfiguration;
385 | buildSettings = {
386 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
387 | DEVELOPMENT_TEAM = 59F6BPBT28;
388 | INFOPLIST_FILE = GCDMulticastDelegateTests/Info.plist;
389 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
390 | PRODUCT_BUNDLE_IDENTIFIER = com.1448.GCDMulticastDelegateTests;
391 | PRODUCT_NAME = "$(TARGET_NAME)";
392 | SWIFT_VERSION = 3.0;
393 | };
394 | name = Release;
395 | };
396 | /* End XCBuildConfiguration section */
397 |
398 | /* Begin XCConfigurationList section */
399 | 9466EB111E600F6C00AE38D9 /* Build configuration list for PBXProject "GCDMulticastDelegate" */ = {
400 | isa = XCConfigurationList;
401 | buildConfigurations = (
402 | 9466EB291E600F6C00AE38D9 /* Debug */,
403 | 9466EB2A1E600F6C00AE38D9 /* Release */,
404 | );
405 | defaultConfigurationIsVisible = 0;
406 | defaultConfigurationName = Release;
407 | };
408 | 9466EB2B1E600F6C00AE38D9 /* Build configuration list for PBXNativeTarget "GCDMulticastDelegate" */ = {
409 | isa = XCConfigurationList;
410 | buildConfigurations = (
411 | 9466EB2C1E600F6C00AE38D9 /* Debug */,
412 | 9466EB2D1E600F6C00AE38D9 /* Release */,
413 | );
414 | defaultConfigurationIsVisible = 0;
415 | defaultConfigurationName = Release;
416 | };
417 | 9466EB2E1E600F6C00AE38D9 /* Build configuration list for PBXNativeTarget "GCDMulticastDelegateTests" */ = {
418 | isa = XCConfigurationList;
419 | buildConfigurations = (
420 | 9466EB2F1E600F6C00AE38D9 /* Debug */,
421 | 9466EB301E600F6C00AE38D9 /* Release */,
422 | );
423 | defaultConfigurationIsVisible = 0;
424 | defaultConfigurationName = Release;
425 | };
426 | /* End XCConfigurationList section */
427 | };
428 | rootObject = 9466EB0E1E600F6C00AE38D9 /* Project object */;
429 | }
430 |
--------------------------------------------------------------------------------