Skip to content

Commit 1a25b4b

Browse files
feat: update swift example apps to use new methods
Signed-off-by: Jonathan Norris <[email protected]>
1 parent 8d0e9bc commit 1a25b4b

File tree

11 files changed

+352
-298
lines changed

11 files changed

+352
-298
lines changed

Examples/DevCycle-MacOS-Example-App/DevCycle-macOS-Example-App.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@
359359
"$(inherited)",
360360
"@executable_path/../Frameworks",
361361
);
362-
MACOSX_DEPLOYMENT_TARGET = 10.13;
362+
MACOSX_DEPLOYMENT_TARGET = 10.15;
363363
MARKETING_VERSION = 1.0;
364364
PRODUCT_BUNDLE_IDENTIFIER = "com.devcycle.DevCycle-MacOS-Example-App";
365365
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -386,7 +386,7 @@
386386
"$(inherited)",
387387
"@executable_path/../Frameworks",
388388
);
389-
MACOSX_DEPLOYMENT_TARGET = 10.13;
389+
MACOSX_DEPLOYMENT_TARGET = 10.15;
390390
MARKETING_VERSION = 1.0;
391391
PRODUCT_BUNDLE_IDENTIFIER = "com.devcycle.DevCycle-MacOS-Example-App";
392392
PRODUCT_NAME = "$(TARGET_NAME)";

Examples/DevCycle-MacOS-Example-App/DevCycle-macOS-Example-App/AppDelegate.swift

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,35 @@ import DevCycle
88

99
@main
1010
class AppDelegate: NSObject, NSApplicationDelegate {
11-
12-
func applicationDidFinishLaunching(_ aNotification: Notification) {
13-
// TODO: Set SDK Key in DevCycleManager.swift
14-
15-
// Insert code here to initialize your application
16-
// create anonymous user
17-
let user = try? DevCycleUser.builder()
18-
.isAnonymous(true)
19-
.build()
20-
21-
// initialize DevCycle
22-
if let user = user {
11+
12+
override init() {
13+
super.init()
14+
do {
15+
// TODO: Set SDK Key in DevCycleManager.swift
16+
17+
// Insert code here to initialize your application
18+
// create anonymous user
19+
let user = try DevCycleUser.builder()
20+
.isAnonymous(true)
21+
.build()
22+
23+
// Initialize DevCycle
2324
DevCycleManager.shared.initialize(user: user)
25+
} catch {
26+
fatalError("Failed to build DevCycleUser: \(error)")
2427
}
2528
}
2629

30+
func applicationDidFinishLaunching(_ aNotification: Notification) {
31+
// No DevCycle initialization needed here
32+
}
33+
2734
func applicationWillTerminate(_ aNotification: Notification) {
2835
// Insert code here to tear down your application
2936
}
3037

3138
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
3239
return true
3340
}
34-
41+
3542
}

Examples/DevCycle-MacOS-Example-App/DevCycle-macOS-Example-App/DevCycleManager.swift

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,39 @@
33
// DevCycle-MacOS-Example-App
44
//
55

6-
import Foundation
76
import DevCycle
7+
import Foundation
88

99
struct DevCycleKeys {
1010
static var DEVELOPMENT = "<DEVCYCLE_MOBILE_SDK_KEY>"
1111
}
1212

1313
class DevCycleManager {
14-
15-
var client: DevCycleClient?
14+
private var client: DevCycleClient?
15+
private var initializationTask: Task<DevCycleClient?, Never>?
1616
static let shared = DevCycleManager()
17-
17+
1818
func initialize(user: DevCycleUser) {
19-
let options = DevCycleOptions.builder()
20-
.logLevel(.debug)
21-
.build()
22-
23-
guard let client = try? DevCycleClient.builder()
19+
print("DVC Manager Initialize")
20+
guard initializationTask == nil else { return }
21+
initializationTask = Task {
22+
let options = DevCycleOptions.builder()
23+
.build()
24+
let client = try? await DevCycleClient.builder()
2425
.sdkKey(DevCycleKeys.DEVELOPMENT)
2526
.user(user)
2627
.options(options)
27-
.build(onInitialized: nil)
28-
else {
29-
return
28+
.build()
29+
print("DVC Manager ")
30+
self.client = client
31+
return client
32+
}
33+
}
34+
35+
var clientAsync: DevCycleClient? {
36+
get async {
37+
print("Get clientAsync")
38+
return await initializationTask?.value
3039
}
31-
self.client = client
3240
}
3341
}

Examples/DevCycle-MacOS-Example-App/DevCycle-macOS-Example-App/ViewController.swift

Lines changed: 79 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,31 @@ class ViewController: NSViewController {
1010

1111
@IBOutlet weak var titleHeader: NSTextField!
1212
@IBOutlet weak var loginButton: NSButton!
13-
13+
1414
var loggedIn: Bool = false
15-
var client: DevCycleClient?
1615
var titleHeaderVar: DVCVariable<String>?
1716
var loginCtaVar: DVCVariable<String>?
18-
17+
1918
override func viewDidLoad() {
2019
super.viewDidLoad()
21-
22-
// Wait for NSApplication.didFinishLaunching as default View Controller calls viewDidLoad() before applicationDidFinishLaunching on macOS
23-
NotificationCenter.default.addObserver(self,
24-
selector: #selector(didFinishLaunching),
25-
name: NSApplication.didFinishLaunchingNotification,
26-
object: nil)
27-
}
28-
29-
@objc func didFinishLaunching() {
30-
// Do any additional setup after loading the view.
31-
self.client = DevCycleManager.shared.client
32-
self.loginCtaVar = client?.variable(key: "login-cta-copy", defaultValue: "Log").onUpdate(handler: { value in
33-
self.setLoginButtonTitle(self.loggedIn)
34-
})
35-
self.titleHeaderVar = client?.variable(key: "title-header-copy", defaultValue: "DevCycle iOS Example App").onUpdate(handler: { value in
20+
21+
Task {
22+
guard let client = await DevCycleManager.shared.clientAsync else { return }
23+
24+
self.loginCtaVar = client.variable(key: "login-cta-copy", defaultValue: "Log")
25+
.onUpdate(handler: { value in
26+
self.setLoginButtonTitle(self.loggedIn)
27+
})
28+
self.titleHeaderVar = client.variable(
29+
key: "title-header-copy", defaultValue: "DevCycle iOS Example App"
30+
).onUpdate(handler: { value in
31+
self.setTitleHeader()
32+
})
3633
self.setTitleHeader()
37-
})
38-
self.setTitleHeader()
39-
self.setLoginButtonTitle(false)
34+
self.setLoginButtonTitle(false)
35+
}
4036
}
41-
37+
4238
func setTitleHeader() {
4339
guard let titleHeaderVar = self.titleHeaderVar else {
4440
return
@@ -51,74 +47,79 @@ class ViewController: NSViewController {
5147
return
5248
}
5349
self.loggedIn = bool
54-
self.loginButton.title = "\(loginCta.value) \(self.loggedIn ? "out" : "in")"
50+
let loggedIn = bool
51+
52+
DispatchQueue.main.async {
53+
self.loginButton.title = "\(loginCta.value) \(loggedIn ? "out" : "in")"
54+
self.loginButton.displayIfNeeded()
55+
}
5556
}
5657

5758
@IBAction func loginButtonPressed(_ sender: Any) {
5859
print("Login Button")
59-
60-
guard let client = self.client else { return }
61-
if (self.loggedIn) {
62-
try? client.resetUser { [weak self] error, variables in
63-
guard let self = self else { return }
64-
self.setLoginButtonTitle(false)
65-
print("Reset User!")
66-
print("Variables: \(String(describing: variables))")
67-
}
68-
} else {
69-
let user = try? DevCycleUser.builder()
70-
.userId("my-user1")
71-
72-
.country("CA")
73-
.name("Ash Ketchum")
74-
.language("EN")
75-
.customData([
76-
"customkey": "customValue"
77-
])
78-
.privateCustomData([
79-
"customkey2": "customValue2"
80-
])
81-
.build()
82-
try? client.identifyUser(user: user!) { [weak self] error, variables in
83-
guard let self = self else { return }
84-
self.setLoginButtonTitle(true)
85-
print("Logged in as User: \(String(describing: user?.userId))!")
86-
print("Variables: \(String(describing: variables))")
87-
88-
let variable = client.variable(key: "num_key", defaultValue: 0)
89-
let variable2 = client.variable(key: "num_key_defaulted", defaultValue: 0)
90-
if (variable.value == 1) {
91-
print("Num_key is 1!")
92-
} else {
93-
print("Num_key is 0!")
60+
let isCurrentlyLoggedIn = self.loggedIn
61+
62+
Task {
63+
guard let client = await DevCycleManager.shared.clientAsync else { return }
64+
if isCurrentlyLoggedIn {
65+
do {
66+
try await client.resetUser()
67+
self.setLoginButtonTitle(false)
68+
print("Reset User!")
69+
} catch {
70+
print("Error resetting user: \(error)")
9471
}
95-
if (variable2.value == 1) {
96-
print("Evaluated num_key_defaulted")
97-
} else {
98-
print("Defaulted num_key_defaulted")
72+
} else {
73+
do {
74+
let user = try DevCycleUser.builder()
75+
.userId("my-user1")
76+
77+
.country("CA")
78+
.name("Ash Ketchum")
79+
.language("EN")
80+
.customData([
81+
"customkey": "customValue"
82+
])
83+
.privateCustomData([
84+
"customkey2": "customValue2"
85+
])
86+
.build()
87+
try await client.identifyUser(user: user)
88+
self.setLoginButtonTitle(true)
89+
print("Logged in as User: \(String(describing: user.userId))!")
90+
let numKeyValue = client.variableValue(key: "num_key", defaultValue: 0)
91+
print("Num_key is \(numKeyValue)!")
92+
let numKeyDefaultedValue = client.variableValue(
93+
key: "num_key_defaulted", defaultValue: 0)
94+
print("Num_key_defaulted is \(numKeyDefaultedValue)!")
95+
} catch {
96+
print("Error identifying user: \(error)")
9997
}
10098
}
10199
}
102100
}
103-
101+
104102
@IBAction func track(_ sender: Any) {
105-
guard let client = self.client else { return }
106-
let event = try! DevCycleEvent.builder()
107-
.type("my_event")
108-
.target("my_target")
109-
.value(3)
110-
.metaData([ "key": "value" ])
111-
.clientDate(Date())
112-
.build()
113-
client.track(event)
114-
print("Tracked event to DevCycle")
103+
Task {
104+
guard let client = await DevCycleManager.shared.clientAsync else { return }
105+
let event = try! DevCycleEvent.builder()
106+
.type("my_event")
107+
.target("my_target")
108+
.value(3)
109+
.metaData(["key": "value"])
110+
.clientDate(Date())
111+
.build()
112+
client.track(event)
113+
print("Tracked event to DevCycle")
114+
}
115115
}
116-
116+
117117
@IBAction func logAllFeatures(_ sender: Any) {
118118
print("logAllFeatures Button Pressed")
119-
guard let client = self.client else { return }
120-
print("All Features: \(client.allFeatures())")
121-
print("All Variables: \(client.allVariables())")
119+
Task {
120+
guard let client = await DevCycleManager.shared.clientAsync else { return }
121+
print("All Features: \(client.allFeatures())")
122+
print("All Variables: \(client.allVariables())")
123+
}
122124
}
123125
}
124-

Examples/DevCycle-MacOS-Example-App/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Uncomment the next line to define a global platform for your project
2-
platform :macos, '10.13'
2+
platform :macos, '10.15'
33

44
target 'DevCycle-macOS-Example-App' do
55
# Comment the next line if you don't want to use dynamic frameworks

Examples/DevCycle-iOS-Example-App-Swift/DevCycle-iOS-Example-App-Swift/AppDelegate.swift

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,52 @@
44
//
55
//
66

7-
import UIKit
87
import DevCycle
8+
import UIKit
99

1010
@main
1111
class AppDelegate: UIResponder, UIApplicationDelegate {
1212

13-
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
14-
// TODO: Set SDK KEY in DevCycleManager.swift
15-
16-
// create anonymous user
17-
let user = try? DevCycleUser.builder()
18-
.isAnonymous(true)
19-
.build()
20-
21-
// initialize DevCycle
22-
if let user = user {
23-
DevCycleManager.shared.initialize(user: user)
13+
func application(
14+
_ application: UIApplication,
15+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
16+
) -> Bool {
17+
do {
18+
// TODO: Set SDK Key in DevCycleManager.swift
19+
20+
// Insert code here to initialize your application
21+
// create anonymous user
22+
let user = try DevCycleUser.builder()
23+
.isAnonymous(true)
24+
.build()
25+
Task {
26+
// Initialize DevCycle
27+
await DevCycleManager.shared.initialize(user: user)
28+
}
29+
} catch {
30+
fatalError("Failed to build DevCycleUser: \(error)")
2431
}
25-
2632
return true
2733
}
2834

2935
// MARK: UISceneSession Lifecycle
3036

31-
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
37+
func application(
38+
_ application: UIApplication,
39+
configurationForConnecting connectingSceneSession: UISceneSession,
40+
options: UIScene.ConnectionOptions
41+
) -> UISceneConfiguration {
3242
// Called when a new scene session is being created.
3343
// Use this method to select a configuration to create the new scene with.
34-
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
44+
return UISceneConfiguration(
45+
name: "Default Configuration", sessionRole: connectingSceneSession.role)
3546
}
3647

37-
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
48+
func application(
49+
_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>
50+
) {
3851
// Called when the user discards a scene session.
3952
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
4053
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
4154
}
4255
}
43-

0 commit comments

Comments
 (0)