Skip to content

Commit 1f46c1e

Browse files
authored
Merge pull request #4 from marty-suzuki/develop
Develop
2 parents 8c96373 + 462992c commit 1f46c1e

File tree

26 files changed

+760
-409
lines changed

26 files changed

+760
-409
lines changed

NoticeObserveKit.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |s|
1010
s.name = 'NoticeObserveKit'
11-
s.version = '0.4.0'
11+
s.version = '0.10.0'
1212
s.summary = 'NoticeObserveKit is type-safe NotificationCenter wrapper that associates notice type with info type.'
1313

1414
# This description is used to generate tags and improve search results.
@@ -28,7 +28,7 @@ Pod::Spec.new do |s|
2828
s.source = { :git => 'https://github.com/marty-suzuki/NoticeObserveKit.git', :tag => s.version.to_s }
2929
s.social_media_url = 'https://twitter.com/marty_suzuki'
3030

31-
s.ios.deployment_target = '8.0'
31+
s.ios.deployment_target = '10.0'
3232

3333
s.source_files = 'NoticeObserveKit/*.{swift}'
3434

NoticeObserveKit/Notice.swift

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
//
2+
// Notice.swift
3+
// NoticeObserveKit
4+
//
5+
// Created by marty-suzuki on 2019/01/25.
6+
//
7+
8+
import Foundation
9+
10+
// MARK: - Notice definition
11+
12+
public enum Notice {
13+
14+
public final class Center {
15+
16+
public static let `default` = Center(center: .default)
17+
18+
let center: NotificationCenter
19+
20+
init(center: NotificationCenter) {
21+
self.center = center
22+
}
23+
}
24+
25+
public class Names {
26+
fileprivate init() {}
27+
}
28+
29+
public final class Name<Value>: Names {
30+
31+
let raw: Notification.Name
32+
33+
public convenience init(name: String) {
34+
self.init(Notification.Name(name))
35+
}
36+
37+
public init(_ name: Notification.Name) {
38+
self.raw = name
39+
super.init()
40+
}
41+
}
42+
43+
public final class Observer {
44+
45+
private(set) weak var center: NotificationCenter?
46+
let raw: NSObjectProtocol
47+
48+
init(center: NotificationCenter, raw: NSObjectProtocol) {
49+
self.center = center
50+
self.raw = raw
51+
}
52+
}
53+
54+
public class ObserverPool {
55+
private(set) var observers: [Observer] = []
56+
private(set) var mutex: pthread_mutex_t = pthread_mutex_t()
57+
58+
public init() {
59+
pthread_mutex_init(&mutex, nil)
60+
}
61+
62+
deinit {
63+
pthread_mutex_lock(&mutex)
64+
observers.forEach {
65+
$0.invalidate()
66+
}
67+
observers.removeAll()
68+
pthread_mutex_unlock(&mutex)
69+
pthread_mutex_destroy(&mutex)
70+
}
71+
72+
func adding(_ observer: Observer) {
73+
pthread_mutex_lock(&mutex)
74+
observers = Array([observers, [observer]].joined())
75+
pthread_mutex_unlock(&mutex)
76+
}
77+
}
78+
}
79+
80+
// MARK: - Notice.Center (NoticeUserInfoDecodable)
81+
82+
extension Notice.Center {
83+
@available(iOS, unavailable)
84+
public func post<Value: NoticeUserInfoDecodable>(name: Notice.Name<Value>, with value: Value, from object: Any? = nil) {}
85+
86+
public func observe<Value: NoticeUserInfoDecodable>(name: Notice.Name<Value>,
87+
object: Any? = nil,
88+
queue: OperationQueue? = nil,
89+
using: @escaping (Value) -> Void) -> Notice.Observer {
90+
let observer = center.addObserver(forName: name.raw, object: object, queue: queue) { notification in
91+
guard
92+
let userInfo = notification.userInfo,
93+
let value = Value(info: userInfo)
94+
else {
95+
return
96+
}
97+
using(value)
98+
}
99+
return Notice.Observer(center: center, raw: observer)
100+
}
101+
}
102+
103+
// MARK: - Notice.Center
104+
105+
extension Notice.Center {
106+
107+
enum Const {
108+
static let infoKey = "noice-info-key"
109+
}
110+
111+
public func post<Value>(name: Notice.Name<Value>, with value: Value, from object: Any? = nil) {
112+
let userInfo: [AnyHashable : Any] = [Const.infoKey : value]
113+
center.post(name: name.raw, object: object, userInfo: userInfo)
114+
}
115+
116+
public func observe<Value>(name: Notice.Name<Value>,
117+
object: Any? = nil,
118+
queue: OperationQueue? = nil,
119+
using: @escaping (Value) -> Void) -> Notice.Observer {
120+
let observer = center.addObserver(forName: name.raw, object: object, queue: queue) { notification in
121+
guard let value = notification.userInfo?[Const.infoKey] as? Value else {
122+
return
123+
}
124+
using(value)
125+
}
126+
return Notice.Observer(center: center, raw: observer)
127+
}
128+
}
129+
130+
// MARK: - Notice.Observer
131+
132+
extension Notice.Observer {
133+
public func invalidate() {
134+
center?.removeObserver(raw)
135+
}
136+
137+
public func invalidated(by pool: Notice.ObserverPool) {
138+
pool.adding(self)
139+
}
140+
}
141+
142+
// MARK: - NotificationCenter extension
143+
144+
extension Notice {
145+
public struct Extension {
146+
let base: Notice.Center
147+
}
148+
}
149+
150+
extension NotificationCenter {
151+
public var nok: Notice.Extension {
152+
return Notice.Extension(base: Notice.Center(center: self))
153+
}
154+
}
155+
156+
extension Notice.Extension {
157+
public func post<Value>(name: Notice.Name<Value>, with value: Value, from object: Any? = nil) {
158+
base.post(name: name, with: value, from: object)
159+
}
160+
161+
public func observe<Value>(name: Notice.Name<Value>,
162+
object: Any? = nil,
163+
queue: OperationQueue? = nil,
164+
using: @escaping (Value) -> Void) -> Notice.Observer {
165+
return base.observe(name: name,
166+
object: object,
167+
queue: queue, using: using)
168+
}
169+
170+
@available(iOS, unavailable)
171+
public func post<Value: NoticeUserInfoDecodable>(name: Notice.Name<Value>, with value: Value, from object: Any? = nil) {}
172+
173+
public func observe<Value: NoticeUserInfoDecodable>(name: Notice.Name<Value>,
174+
object: Any? = nil,
175+
queue: OperationQueue? = nil,
176+
using: @escaping (Value) -> Void) -> Notice.Observer {
177+
return base.observe(name: name,
178+
object: object,
179+
queue: queue,
180+
using: using)
181+
}
182+
}

NoticeObserveKit/NoticeObserveKit.swift

Lines changed: 8 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66
//
77
//
88

9-
import UIKit
9+
import Foundation
10+
11+
public typealias NoticeObserver = Notice.Observer
12+
public typealias NoticeObserverPool = Notice.ObserverPool
1013

1114
//MARK: - NoticeType
15+
@available(iOS, deprecated: 10)
1216
public protocol NoticeType {
1317
associatedtype InfoType
1418
static var name: Notification.Name { get }
@@ -24,15 +28,16 @@ public extension NoticeType {
2428
}
2529

2630
static func observe(queue: OperationQueue? = .main, object: Any? = nil, recieving notiBlock: ((Notification) -> ())? = nil, using infoBlock: @escaping (InfoType) -> ()) -> NoticeObserver {
27-
let observer = NotificationCenter.default.addObserver(forName: name, object: object, queue: queue) { notification in
31+
let center = NotificationCenter.default
32+
let observer = center.addObserver(forName: name, object: object, queue: queue) { notification in
2833
notiBlock?(notification)
2934
guard
3035
let userInfo = notification.userInfo,
3136
let info = decode(userInfo)
3237
else { return }
3338
infoBlock(info)
3439
}
35-
return NoticeObserver(observer: observer)
40+
return NoticeObserver(center: center, raw: observer)
3641
}
3742

3843
static func post(from object: Any? = nil, info: InfoType? = nil) {
@@ -67,51 +72,3 @@ public extension NoticeType where InfoType: NoticeUserInfoDecodable {
6772
public protocol NoticeUserInfoDecodable {
6873
init?(info: [AnyHashable : Any])
6974
}
70-
71-
//MARK: - NoticeObserver
72-
public struct NoticeObserver {
73-
private let observer: NSObjectProtocol
74-
75-
public init(observer: NSObjectProtocol) {
76-
self.observer = observer
77-
}
78-
79-
@available(*, deprecated: 0.11.0)
80-
public func addObserverTo(_ pool: NoticeObserverPool) {
81-
pool.adding(observer)
82-
}
83-
84-
public func disposed(by pool: NoticeObserverPool) {
85-
pool.adding(observer)
86-
}
87-
88-
public func dispose() {
89-
NotificationCenter.default.removeObserver(observer)
90-
}
91-
}
92-
93-
//MARK: - NoticeObserverPool
94-
public class NoticeObserverPool {
95-
private var observers: [NSObjectProtocol] = []
96-
private var mutex: pthread_mutex_t = pthread_mutex_t()
97-
98-
public init() {
99-
pthread_mutex_init(&mutex, nil)
100-
}
101-
102-
deinit {
103-
pthread_mutex_lock(&mutex)
104-
observers.forEach {
105-
NotificationCenter.default.removeObserver($0)
106-
}
107-
observers.removeAll()
108-
pthread_mutex_unlock(&mutex)
109-
pthread_mutex_destroy(&mutex)
110-
}
111-
112-
fileprivate func adding(_ observer: NSObjectProtocol) {
113-
pthread_mutex_lock(&mutex)
114-
observers = Array([observers, [observer]].joined())
115-
pthread_mutex_unlock(&mutex)
116-
}
117-
}

0 commit comments

Comments
 (0)