Skip to content

Commit d675b4e

Browse files
authored
Merge pull request #19 from sgr-ksmt/update_podspec
2 parents ac7e4b3 + 6b0df06 commit d675b4e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2117
-168
lines changed

.jazzy.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,7 @@ custom_categories:
6363
- ConfigDecodableBridge
6464
- ConfigCodableBridge
6565
- ConfigArrayBridge
66-
- ConfigRawRepresentableArrayBridge
66+
- ConfigRawRepresentableArrayBridge
67+
- name: Combine Extension
68+
children:
69+
- ConbineLobster

Demo/Demo.xcodeproj/project.pbxproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
/* End PBXBuildFile section */
2020

2121
/* Begin PBXFileReference section */
22-
162860D41FAA4852003D85A6 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
22+
162860D41FAA4852003D85A6 /* Lobster Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Lobster Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2323
162860D71FAA4852003D85A6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
2424
162860D91FAA4852003D85A6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
2525
162860DC1FAA4852003D85A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
@@ -59,7 +59,7 @@
5959
162860D51FAA4852003D85A6 /* Products */ = {
6060
isa = PBXGroup;
6161
children = (
62-
162860D41FAA4852003D85A6 /* Demo.app */,
62+
162860D41FAA4852003D85A6 /* Lobster Demo.app */,
6363
);
6464
name = Products;
6565
sourceTree = "<group>";
@@ -116,7 +116,7 @@
116116
);
117117
name = Demo;
118118
productName = Demo;
119-
productReference = 162860D41FAA4852003D85A6 /* Demo.app */;
119+
productReference = 162860D41FAA4852003D85A6 /* Lobster Demo.app */;
120120
productType = "com.apple.product-type.application";
121121
};
122122
/* End PBXNativeTarget section */
@@ -361,7 +361,7 @@
361361
INFOPLIST_FILE = Demo/Info.plist;
362362
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
363363
PRODUCT_BUNDLE_IDENTIFIER = demo.lobster;
364-
PRODUCT_NAME = "$(TARGET_NAME)";
364+
PRODUCT_NAME = "Lobster Demo";
365365
SWIFT_VERSION = 5.0;
366366
TARGETED_DEVICE_FAMILY = "1,2";
367367
};
@@ -376,7 +376,7 @@
376376
INFOPLIST_FILE = Demo/Info.plist;
377377
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
378378
PRODUCT_BUNDLE_IDENTIFIER = demo.lobster;
379-
PRODUCT_NAME = "$(TARGET_NAME)";
379+
PRODUCT_NAME = "Lobster Demo";
380380
SWIFT_VERSION = 5.0;
381381
TARGETED_DEVICE_FAMILY = "1,2";
382382
};

Demo/Podfile.lock

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ PODS:
3535
- "GoogleUtilities/NSData+zlib (6.7.1)"
3636
- GoogleUtilities/UserDefaults (6.7.1):
3737
- GoogleUtilities/Logger
38-
- Lobster (2.2):
39-
- Firebase/RemoteConfig (~> 6.0)
38+
- Lobster (3.0.0):
39+
- Firebase/RemoteConfig (~> 6.29)
40+
- Lobster/Core (= 3.0.0)
41+
- Lobster/Core (3.0.0):
42+
- Firebase/RemoteConfig (~> 6.29)
4043
- nanopb (1.30905.0):
4144
- nanopb/decode (= 1.30905.0)
4245
- nanopb/encode (= 1.30905.0)
@@ -48,7 +51,7 @@ DEPENDENCIES:
4851
- Lobster (from `../`)
4952

5053
SPEC REPOS:
51-
https://cdn.cocoapods.org/:
54+
trunk:
5255
- Firebase
5356
- FirebaseABTesting
5457
- FirebaseCore
@@ -73,10 +76,10 @@ SPEC CHECKSUMS:
7376
FirebaseRemoteConfig: 521ff38593bed36fcb6f466fb6fffa99a753d783
7477
GoogleDataTransport: af0c79193dc59acd37630b4833d0dc6912ae6bd5
7578
GoogleUtilities: e121a3867449ce16b0e35ddf1797ea7a389ffdf2
76-
Lobster: b7c48cf6ff48e80f269715ce80cdc3e087c7b501
79+
Lobster: 07e4f45919483efa3b5d68ba74f424dd462a5de7
7780
nanopb: c43f40fadfe79e8b8db116583945847910cbabc9
7881
PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75
7982

8083
PODFILE CHECKSUM: c6efd56fba58da5968399c93e6f38bb7f1692d81
8184

82-
COCOAPODS: 1.9.1
85+
COCOAPODS: 1.9.3

Demo/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
## Demo
1+
# Lobster example app with Swift
2+
3+
## Setup
24

35
```bash
46
$ cd path/to/Lobster
57
$ make
68
$ cd ./Demo
79
$ bundle exec pod install
810
$ open Demo.xcworkspace
9-
```
11+
```
12+
13+
You need to place `GoogleService-Info.plist` into `Lobster/Demo/Demo`.
14+
Also, You have to set bundle identifiher `demo.lobster`.

Lobster.podspec

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,27 @@ Pod::Spec.new do |spec|
55
spec.summary = 'The Type-safe Firebase-RemoteConfig helper library'
66
spec.homepage = 'https://github.com/sgr-ksmt/Lobster'
77
spec.license = { :type => 'MIT', :file => 'LICENSE' }
8-
98
spec.source = { :git => 'https://github.com/sgr-ksmt/Lobster.git', :tag => spec.version.to_s }
109

1110
spec.ios.deployment_target = '11.0'
12-
1311
spec.swift_versions = ['4.2', '5.0']
1412

1513
spec.requires_arc = true
1614
spec.static_framework = true
17-
spec.source_files = 'Sources/**/*'
1815

1916
spec.dependency 'Firebase/RemoteConfig', '~> 6.29'
17+
18+
spec.default_subspecs = 'Core'
19+
20+
spec.subspec 'Core' do |subspec|
21+
subspec.source_files = 'Sources/Core/**/*.swift'
22+
end
23+
24+
spec.subspec 'Combine' do |subspec|
25+
subspec.dependency 'Lobster/Core'
26+
subspec.source_files = 'Sources/Combine/**/*.swift'
27+
28+
subspec.ios.deployment_target = '13.0'
29+
subspec.ios.frameworks = 'Combine'
30+
end
2031
end

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ pod-install:
1010
bundle exec pod install || bundle exec pod install --repo-update
1111

1212
gen-docs:
13-
bundle exec jazzy --config .jazzy.yaml
13+
bundle exec jazzy --config .jazzy.yaml
14+
15+
pod-lib-lint:
16+
bundle exec pod lib lint --allow-warnings

README.md

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Lobster
2+
23
Type-safe Firebase-RemoteConfig helper library.
34

45

@@ -9,19 +10,23 @@ Type-safe Firebase-RemoteConfig helper library.
910
[![CocoaPods](https://img.shields.io/badge/Cocoa%20Pods-compatible-4BC51D.svg?style=for-the-badge)](https://cocoapods.org/pods/Lobster)
1011

1112
## Feature
13+
1214
- Can get a value from RemoteConfig / set a value to RemoteConfig to type-safe.
1315
- Easy to set default value to RemoteConfig by using key-value subscripting.
1416
- Custom type available ✨
1517
- `String`/`Int` enum
1618
- `Decodable`(read-only) and `Codable`.
1719
- Can manage expiration duration of config values.
20+
- Combine framwork support.
1821

1922
---
2023

2124
## Getting Started
2225

2326
- [API Documentation](https://sgr-ksmt.github.io/Lobster/index.html)
24-
- [Example Apps](https://github.com/sgr-ksmt/Lobster/tree/master/Demo)
27+
- Example Apps
28+
- [Swift Demo](https://github.com/sgr-ksmt/Lobster/tree/master/Demo)
29+
- [SwiftUI + Combine Demo](https://github.com/sgr-ksmt/Lobster/tree/master/SwiftUI-Demo)
2530

2631
## Basic Usage
2732

@@ -63,20 +68,38 @@ Lobster.shared.fetch { _ in
6368
}
6469
```
6570

66-
6771
## Tips for you
6872

69-
### Fetch latest value from remote.
73+
### Combine
74+
75+
You can get values from Lobster with Combine's stream.
76+
Here is a sampl viewmodel class.
7077

7178
```swift
72-
Lobster.shared.fetch { [weak self] error in
73-
if let error = error {
74-
print(error)
79+
import Lobster
80+
import Combine
81+
82+
extension ConfigKeys {
83+
static let title = ConfigKey<String>("title")
84+
}
85+
86+
final class ViewModel: ObservableObject {
87+
@Published var title: String
88+
private var cancellables: Set<AnyCancellable> = []
89+
90+
init() {
91+
title = Lobster.shared[.titleText]
92+
93+
Lobster.shared.combine.fetched(.title)
94+
.receive(on: RunLoop.main)
95+
.assign(to: \.title, on: self)
96+
.store(in: &cancellables)
7597
}
76-
self?.titleLabel.text = Lobster.shared[.titleText]
7798
}
7899
```
79100

101+
NOTE: You need to install `Lobster/Combine` before using it.
102+
80103
### Get value with subscripting syntax.
81104

82105
Use subscripting syntax.
@@ -333,6 +356,9 @@ it, simply add the following line to your Podfile:
333356

334357
```ruby
335358
pod 'Lobster', '~> 3.0.0'
359+
360+
# If you want to use extensions of Combine, please install below:
361+
pod 'Lobster/Combine'
336362
```
337363

338364
and run `pod install`

Sources/Combine/Lobster+Combine.swift

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
import Foundation
55
import Combine
66

7+
/// CombineLobster is a extension class with Combine.
8+
///
9+
/// It allows you handle Lobster with Combine
710
@available(iOS 13.0, *)
811
public struct CombineLobster {
912
fileprivate let lobster: Lobster
1013
}
1114

1215
@available(iOS 13.0, *)
13-
public extension CombineLobster {
14-
16+
extension CombineLobster {
1517
class Subscription<S: Subscriber> {
1618
var subscriber: S?
1719
var cancellable: AnyCancellable?
@@ -38,7 +40,7 @@ public extension CombineLobster {
3840
}
3941
}
4042

41-
final class ConfigValueSubscription<S: Subscriber, T: ConfigSerializable>: Subscription<S>, Combine.Subscription where S.Input == T.Value, S.Failure == Error {
43+
final class ConfigValueSubscription<S: Subscriber, T: ConfigSerializable>: Subscription<S>, Combine.Subscription where S.Input == T.Value, S.Failure == Never {
4244
private let key: ConfigKey<T>
4345
init(subscriber: S, lobster: Lobster, key: ConfigKey<T>) {
4446
self.key = key
@@ -58,7 +60,7 @@ public extension CombineLobster {
5860

5961
struct ConfigValuePublisher<T: ConfigSerializable>: Combine.Publisher {
6062
public typealias Output = T.Value
61-
public typealias Failure = Error
63+
public typealias Failure = Never
6264

6365
private let lobster: Lobster
6466
private let key: ConfigKey<T>
@@ -77,7 +79,7 @@ public extension CombineLobster {
7779
}
7880
}
7981

80-
final class ConfigValueOptionalSubscription<S: Subscriber, T: ConfigSerializable>: Subscription<S>, Combine.Subscription where S.Input == T.Value?, S.Failure == Error {
82+
final class ConfigValueOptionalSubscription<S: Subscriber, T: ConfigSerializable>: Subscription<S>, Combine.Subscription where S.Input == T.Value?, S.Failure == Never {
8183
private let key: ConfigKey<T?>
8284
init(subscriber: S, lobster: Lobster, key: ConfigKey<T?>) {
8385
self.key = key
@@ -97,7 +99,7 @@ public extension CombineLobster {
9799

98100
struct ConfigValueOptionalPublisher<T: ConfigSerializable>: Combine.Publisher {
99101
public typealias Output = T.Value?
100-
public typealias Failure = Error
102+
public typealias Failure = Never
101103

102104
private let lobster: Lobster
103105
private let key: ConfigKey<T?>
@@ -118,15 +120,21 @@ public extension CombineLobster {
118120

119121
}
120122

123+
/// Extensions for Lobster
121124
@available(iOS 13.0, *)
122125
public extension Lobster {
126+
/// Returns `CombineLobster`.
123127
var combine: CombineLobster {
124128
CombineLobster(lobster: self)
125129
}
126130
}
127131

132+
/// Extensions for CombineLobster
128133
@available(iOS 13.0, *)
129134
public extension CombineLobster {
135+
/// Returns Publisher that tells you that Lobster has fetched latest valeus from RemoteConfig.
136+
///
137+
/// - Returns: A publisher `<Void, Error>`
130138
func fetched() -> AnyPublisher<Void, Error> {
131139
return NotificationCenter.default.publisher(for: Lobster.didFetchConfig)
132140
.tryMap { (notification) in
@@ -138,12 +146,18 @@ public extension CombineLobster {
138146
.eraseToAnyPublisher()
139147
}
140148

141-
func fetched<T: ConfigSerializable>(_ key: ConfigKey<T>) -> AnyPublisher<T.Value, Error> {
149+
/// Returns Publisher that gives you a value matched a config key after fetching from RemoteConfig.
150+
///
151+
/// - Returns: A publisher `<T.Value, Error>`
152+
func fetched<T: ConfigSerializable>(_ key: ConfigKey<T>) -> AnyPublisher<T.Value, Never> {
142153
return ConfigValuePublisher(lobster: lobster, key: key)
143154
.eraseToAnyPublisher()
144155
}
145156

146-
func fetched<T: ConfigSerializable>(_ key: ConfigKey<T?>) -> AnyPublisher<T.Value?, Error> {
157+
/// Returns Publisher that gives you an optional value matched a config key after fetching from RemoteConfig.
158+
///
159+
/// - Returns: A publisher `<T.Value?, Error>`
160+
func fetched<T: ConfigSerializable>(_ key: ConfigKey<T?>) -> AnyPublisher<T.Value?, Never> {
147161
return ConfigValueOptionalPublisher(lobster: lobster, key: key)
148162
.eraseToAnyPublisher()
149163
}

Sources/Core/Extensions/UIColor+Ex.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import UIKit
66
extension String {
77
var hexColor: UIColor {
88
let hex = trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
9-
var int = UInt32()
10-
Scanner(string: hex).scanHexInt32(&int)
11-
let a, r, g, b: UInt32
9+
var int = UInt64()
10+
Scanner(string: hex).scanHexInt64(&int)
11+
let a, r, g, b: UInt64
1212
switch hex.count {
1313
case 3:
1414
(r, g, b, a) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17, 255)

SwiftUI-Demo/Podfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
platform :ios, '13.0'
2+
3+
inhibit_all_warnings!
4+
use_frameworks!
5+
6+
target 'SwiftUI-Demo' do
7+
pod 'Lobster', :path => '../'
8+
pod 'Lobster/Combine', :path => '../'
9+
end

0 commit comments

Comments
 (0)