Skip to content

Commit 0444e63

Browse files
1. Separate out login/logout.
2. Better handling of apiKey not present situation.
1 parent 893b727 commit 0444e63

File tree

10 files changed

+355
-36
lines changed

10 files changed

+355
-36
lines changed

sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
ACA3A14320E2F6B100FEF74F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = ACA3A14120E2F6B100FEF74F /* LaunchScreen.storyboard */; };
2121
ACA3A15120E2F83E00FEF74F /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA3A15020E2F83E00FEF74F /* NotificationService.swift */; };
2222
ACA3A15520E2F83E00FEF74F /* swift-sample-app-notification-extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = ACA3A14E20E2F83D00FEF74F /* swift-sample-app-notification-extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
23+
ACE7624B20FEB2C20040A002 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACE7624A20FEB2C20040A002 /* LoginViewController.swift */; };
24+
ACF0A43A20FE8C50004B59EB /* APIKeyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACF0A43920FE8C50004B59EB /* APIKeyViewController.swift */; };
2325
/* End PBXBuildFile section */
2426

2527
/* Begin PBXContainerItemProxy section */
@@ -65,6 +67,8 @@
6567
ACA3A15020E2F83E00FEF74F /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
6668
ACA3A15220E2F83E00FEF74F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6769
ACA3A16420E2FC7500FEF74F /* swift-sample-app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "swift-sample-app.entitlements"; sourceTree = "<group>"; };
70+
ACE7624A20FEB2C20040A002 /* LoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = "<group>"; };
71+
ACF0A43920FE8C50004B59EB /* APIKeyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIKeyViewController.swift; sourceTree = "<group>"; };
6872
ACFA148520E3033700AF4A5A /* CoffeeType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoffeeType.swift; sourceTree = "<group>"; };
6973
EE45F561E7E4376F9C089941 /* Pods-swift-sample-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-swift-sample-app.release.xcconfig"; path = "Pods/Target Support Files/Pods-swift-sample-app/Pods-swift-sample-app.release.xcconfig"; sourceTree = "<group>"; };
7074
EF740C567615690E8C39C769 /* Pods-swift-sample-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-swift-sample-app.debug.xcconfig"; path = "Pods/Target Support Files/Pods-swift-sample-app/Pods-swift-sample-app.debug.xcconfig"; sourceTree = "<group>"; };
@@ -104,6 +108,8 @@
104108
children = (
105109
AC5ECD9E20E304000081E1DA /* CoffeeListTableViewController.swift */,
106110
AC5ECD9F20E304070081E1DA /* CoffeeViewController.swift */,
111+
ACF0A43920FE8C50004B59EB /* APIKeyViewController.swift */,
112+
ACE7624A20FEB2C20040A002 /* LoginViewController.swift */,
107113
);
108114
name = ViewControllers;
109115
sourceTree = "<group>";
@@ -378,7 +384,9 @@
378384
files = (
379385
AC1BDF5A20E304CC000010CA /* CoffeeViewController.swift in Sources */,
380386
ACA3A13920E2F6AF00FEF74F /* AppDelegate.swift in Sources */,
387+
ACF0A43A20FE8C50004B59EB /* APIKeyViewController.swift in Sources */,
381388
AC1BDF5920E304BF000010CA /* DeeplinkHandler.swift in Sources */,
389+
ACE7624B20FEB2C20040A002 /* LoginViewController.swift in Sources */,
382390
AC1BDF5C20E304D7000010CA /* CoffeeType.swift in Sources */,
383391
AC1BDF5B20E304D1000010CA /* UIViewController+Extension.swift in Sources */,
384392
AC1BDF5820E304BC000010CA /* CoffeeListTableViewController.swift in Sources */,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// SettingsViewController.swift
3+
// swift-sample-app
4+
//
5+
// Created by Tapash Majumder on 7/17/18.
6+
// Copyright © 2018 Iterable. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
class APIKeyViewController: UIViewController {
12+
@IBOutlet weak var apiKeyTextField: UITextField!
13+
14+
override func viewDidLoad() {
15+
super.viewDidLoad()
16+
17+
}
18+
19+
@IBAction func setApiKeyTapped(_ sender: UIButton) {
20+
guard let text = apiKeyTextField.text, !text.isEmpty else {
21+
let alert = UIAlertController(title: "API Key Required", message: "Please enter your Iterable API Key.", preferredStyle: .alert)
22+
let action = UIAlertAction(title: "OK", style: .default) { (action) in
23+
self.apiKeyTextField.becomeFirstResponder()
24+
}
25+
alert.addAction(action)
26+
present(alert, animated: true)
27+
return
28+
}
29+
30+
UserDefaults.standard.set(text, forKey: "iterableApiKey")
31+
32+
let alert = UIAlertController(title: "Relaunch Application", message: "Your Iterable API Key has been set. You need to launch the application again. Application will now exit.", preferredStyle: .alert)
33+
let action = UIAlertAction(title: "OK", style: .default) { (action) in
34+
exit(0)
35+
}
36+
alert.addAction(action)
37+
present(alert, animated: true)
38+
}
39+
}

sample-apps/swift-sample-app/swift-sample-app/AppDelegate.swift

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,38 @@ import IterableSDK
1313

1414
@UIApplicationMain
1515
class AppDelegate: UIResponder, UIApplicationDelegate {
16-
// ITBL: replace with your api key and email.
17-
// IMP: Either userId or email must be set.
18-
let apiKey = "" // set Iterable api key here
19-
let email = "" // set Iterable user email here.
20-
let userId = "" // set iterable userId here. Either email or userId must be set.
21-
2216
var window: UIWindow?
2317

2418
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
25-
// Initial check
26-
if apiKey.isEmpty || (email.isEmpty && userId.isEmpty) {
27-
fatalError("Iterable API Key and either email or userId need to be set.")
28-
}
29-
19+
3020
//ITBL: Setup Notification
3121
setupNotifications()
3222

3323
//ITBL: Initialize API
34-
let config = IterableConfig()
35-
config.customActionDelegate = self
36-
config.urlDelegate = self
37-
config.pushIntegrationName = "swift-sample-app"
38-
config.sandboxPushIntegrationName = "swift-sample-app"
39-
// Replace with your api key and email here.
40-
IterableAPI.initialize(apiKey: apiKey,
41-
launchOptions:launchOptions,
42-
config: config)
43-
IterableAPI.email = email
24+
// NOTE: In your application you should hard-code your Iterable API Key. No need to
25+
// save in UserDefaults
26+
if let iterableApiKey = UserDefaults.standard.string(forKey: "iterableApiKey") {
27+
// You code sould always come here in your actual application
28+
let config = IterableConfig()
29+
config.customActionDelegate = self
30+
config.urlDelegate = self
31+
config.pushIntegrationName = "swift-sample-app"
32+
config.sandboxPushIntegrationName = "swift-sample-app"
33+
// Replace with your api key and email here.
34+
IterableAPI.initialize(apiKey: iterableApiKey,
35+
launchOptions:launchOptions,
36+
config: config)
37+
} else {
38+
// Your code should never come here in your actual application
39+
// For this sample app we don't know the Iterable API Key that's why we have it here.
40+
let storyboard = UIStoryboard(name: "Main", bundle: nil)
41+
let apiKeyVC = storyboard.instantiateViewController(withIdentifier: "APIKeyViewController")
42+
window?.rootViewController = apiKeyVC
43+
}
4444

4545
return true
4646
}
47-
47+
4848
func applicationWillResignActive(_ application: UIApplication) {
4949
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
5050
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
@@ -146,4 +146,3 @@ extension AppDelegate : IterableCustomActionDelegate {
146146
return false
147147
}
148148
}
149-
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"idiom" : "universal",
5+
"filename" : "iterableLogo.pdf"
6+
}
7+
],
8+
"info" : {
9+
"version" : 1,
10+
"author" : "xcode"
11+
}
12+
}
Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,50 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="PB5-Tr-D5w">
3+
<device id="retina4_7" orientation="portrait">
4+
<adaptation id="fullscreen"/>
5+
</device>
36
<dependencies>
4-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
7+
<deployment identifier="iOS"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
59
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
610
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
711
</dependencies>
812
<scenes>
9-
<!--View Controller-->
10-
<scene sceneID="EHf-IW-A2E">
13+
<!--APIKey View Controller-->
14+
<scene sceneID="2UB-Cd-P2g">
1115
<objects>
12-
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
13-
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
16+
<viewController storyboardIdentifier="APIKeyViewController" id="PB5-Tr-D5w" userLabel="APIKey View Controller" sceneMemberID="viewController">
17+
<view key="view" contentMode="scaleToFill" id="hDo-Q9-Uge">
1418
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
1519
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16-
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
17-
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
20+
<subviews>
21+
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="50" translatesAutoresizingMaskIntoConstraints="NO" id="g0R-UU-Rrn">
22+
<rect key="frame" x="40" y="170" width="295" height="33"/>
23+
<subviews>
24+
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="iterableLogo" translatesAutoresizingMaskIntoConstraints="NO" id="Pnl-gI-tgF">
25+
<rect key="frame" x="0.0" y="0.0" width="295" height="33"/>
26+
</imageView>
27+
</subviews>
28+
</stackView>
29+
</subviews>
30+
<color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
31+
<color key="tintColor" red="0.31372549020000001" green="0.71372549019999998" blue="0.98823529409999999" alpha="1" colorSpace="calibratedRGB"/>
32+
<gestureRecognizers/>
33+
<constraints>
34+
<constraint firstItem="g0R-UU-Rrn" firstAttribute="leading" secondItem="Jl2-yu-Mpj" secondAttribute="leading" constant="40" id="ME5-Gw-gWZ"/>
35+
<constraint firstItem="Jl2-yu-Mpj" firstAttribute="trailing" secondItem="g0R-UU-Rrn" secondAttribute="trailing" constant="40" id="Zv1-qV-U6x"/>
36+
<constraint firstItem="g0R-UU-Rrn" firstAttribute="top" secondItem="Jl2-yu-Mpj" secondAttribute="top" constant="150" id="ihm-wH-fku"/>
37+
</constraints>
38+
<viewLayoutGuide key="safeArea" id="Jl2-yu-Mpj"/>
1839
</view>
1940
</viewController>
20-
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
41+
<placeholder placeholderIdentifier="IBFirstResponder" id="GWS-hd-2WK" sceneMemberID="firstResponder"/>
42+
<tapGestureRecognizer id="0v3-GZ-kKa"/>
2143
</objects>
22-
<point key="canvasLocation" x="53" y="375"/>
44+
<point key="canvasLocation" x="119" y="140"/>
2345
</scene>
2446
</scenes>
47+
<resources>
48+
<image name="iterableLogo" width="143" height="33"/>
49+
</resources>
2550
</document>

0 commit comments

Comments
 (0)