Skip to content
Permalink
Browse files
code change : 3. Add Auth
  • Loading branch information
Stormacq, Sebastien committed Jun 11, 2020
1 parent d5e5132 commit 675318f3df24b3893ba849e19214ce719a6b7445
Showing 7 changed files with 217 additions and 12 deletions.
@@ -6,12 +6,66 @@ The application delegate.
*/

import UIKit
import Amplify
import AmplifyPlugins

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

public let userData = UserData()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

do {
Amplify.Logging.logLevel = .info
try Amplify.add(plugin: AWSCognitoAuthPlugin())

try Amplify.configure()
print("Amplify initialized")

// load data when user is signedin
self.checkUserSignedIn()

// listen to auth events.
// see https://github.com/aws-amplify/amplify-ios/blob/master/Amplify/Categories/Auth/Models/AuthEventName.swift
_ = Amplify.Hub.listen(to: .auth) { (payload) in

switch payload.eventName {

case HubPayload.EventName.Auth.signedIn:
print("==HUB== User signed In, update UI")

self.updateUI(forSignInStatus: true)

// if you want to get user attributes
_ = Amplify.Auth.fetchUserAttributes() { (result) in
switch result {
case .success(let attributes):
print("User attribtues - \(attributes)")
case .failure(let error):
print("Fetching user attributes failed with error \(error)")
}
}


case HubPayload.EventName.Auth.signedOut:
print("==HUB== User signed Out, update UI")
self.updateUI(forSignInStatus: false)

case HubPayload.EventName.Auth.sessionExpired:
print("==HUB== Session expired, show sign in aui")
self.updateUI(forSignInStatus: false)

default:
//print("==HUB== \(payload)")
break
}
}

} catch {
print("Failed to configure Amplify \(error)")
}

return true
}

@@ -31,6 +85,60 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

// MARK: -- Authentication code
// change our internal state, this triggers an UI update on the main thread
func updateUI(forSignInStatus : Bool) {
DispatchQueue.main.async() {
self.userData.isSignedIn = forSignInStatus
}
}

// when user is signed in, fetch its details
func checkUserSignedIn() {

}
// every time auth status changes, let's check if user is signedIn or not
// updating userData will automatically update the UI
_ = Amplify.Auth.fetchAuthSession { (result) in

do {
let session = try result.get()
self.updateUI(forSignInStatus: session.isSignedIn)
} catch {
print("Fetch auth session failed with error - \(error)")
}

}
}

// signin with Cognito web user interface
public func authenticateWithHostedUI() {

print("hostedUI()")
_ = Amplify.Auth.signInWithWebUI(presentationAnchor: UIApplication.shared.windows.first!) { result in
switch result {
case .success(_):
print("Sign in succeeded")
case .failure(let error):
print("Sign in failed \(error)")
}
}
}

// signout globally
public func signOut() {

// https://docs.amplify.aws/lib/auth/signOut/q/platform/ios
let options = AuthSignOutRequest.Options(globalSignOut: true)
_ = Amplify.Auth.signOut(options: options) { (result) in
switch result {
case .success:
print("Successfully signed out")
case .failure(let error):
print("Sign out failed with error \(error)")
}
}
}

}
@@ -2,6 +2,19 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

<!-- ADD AN ENTRY TO CFBundleURLTypes for Cognito Auth -->
<!-- IF YOU DO NOT HAVE CFBundleURLTypes, YOU CAN COPY THE WHOLE BLOCK BELOW -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>landmarks</string>
</array>
</dict>
</array>

<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
@@ -0,0 +1,37 @@
//
// LandingView.swift
// Landmarks
// Landmarks/LandingView.swift
import SwiftUI

struct LandingView: View {
@ObservedObject public var user : UserData

var body: some View {

return VStack {
// .wrappedValue is used to extract the Bool from Binding<Bool> type
if (!$user.isSignedIn.wrappedValue) {

Button(action: {
let app = UIApplication.shared.delegate as! AppDelegate
app.authenticateWithHostedUI()
}) {
UserBadge().scaleEffect(0.5)
}

} else {
LandmarkList().environmentObject(user)
}
}
}
}

struct LandingView_Previews: PreviewProvider {
static var previews: some View {
let app = UIApplication.shared.delegate as! AppDelegate
return LandingView(user: app.userData)
}
}
@@ -7,6 +7,18 @@ A view showing a list of landmarks.

import SwiftUI

struct SignOutButton : View {
let app = UIApplication.shared.delegate as! AppDelegate

var body: some View {
NavigationLink(destination: LandingView(user: app.userData)) {
Button(action: { self.app.signOut() }) {
Text("Sign Out")
}
}
}
}

struct LandmarkList: View {
@EnvironmentObject private var userData: UserData

@@ -29,6 +41,7 @@ struct LandmarkList: View {
}
}
.navigationBarTitle(Text("Landmarks"))
.navigationBarItems(trailing: SignOutButton())
}
}
}
@@ -1,14 +1,9 @@
/*
See LICENSE folder for this sample’s licensing information.
Abstract:
A model object that stores app data.
*/

// Landmarks/Models/UserData.swift
import Combine
import SwiftUI

final class UserData: ObservableObject {
@Published var showFavoritesOnly = false
@Published var landmarks = landmarkData
@Published var isSignedIn : Bool = false
}
@@ -11,7 +11,8 @@ import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

let app = UIApplication.shared.delegate as! AppDelegate

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
@@ -20,7 +21,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// Use a UIHostingController as window root view controller
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: LandmarkList().environmentObject(UserData()))

window.rootViewController = UIHostingController(rootView: LandingView(user: app.userData))

self.window = window
window.makeKeyAndVisible()
}
@@ -55,4 +58,3 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
}

}

@@ -0,0 +1,37 @@
//
// UserBadge.swift
// Landmarks
import SwiftUI

struct UserBadge: View {
var body: some View {
GeometryReader { geometry in
ZStack {
Circle().stroke(Color.blue, lineWidth: geometry.size.width/50.0)

VStack {
Circle()
.frame(width:geometry.size.width / 2.0, height:geometry.size.width / 2.0, alignment: .center)
.foregroundColor(.blue)
.offset(x:0, y:geometry.size.width/3.3)

Circle()
.frame(width:geometry.size.width, height:geometry.size.width, alignment: .center)
.foregroundColor(.blue)
.offset(x:0, y:geometry.size.width/3.0)


}
}
.clipShape(Circle())
.shadow(radius: geometry.size.width/30.0)
}
}
}

struct UserBadge_Previews: PreviewProvider {
static var previews: some View {
UserBadge()
}
}

0 comments on commit 675318f

Please sign in to comment.