Last active
July 10, 2020 22:46
-
-
Save alperen23230/224eac8153690b0c4b1e6fa408580482 to your computer and use it in GitHub Desktop.
SwiftUI and Combine Codes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import Combine | |
enum ErrorType { | |
case badRequest, authError, outdatedError, undefined | |
} | |
struct APIError: Error { | |
let statusCode: Int | |
var errorDescription: ErrorType { | |
switch statusCode { | |
case 401...500: | |
return .authError | |
case 501...599: | |
return .badRequest | |
case 600: | |
return .outdatedError | |
default: | |
return .undefined | |
} | |
} | |
} | |
struct APIService { | |
func fetchWithURLRequest<T: Decodable>(_ urlRequest: URLRequest) -> AnyPublisher<T, Error> { | |
URLSession.shared.dataTaskPublisher(for: urlRequest) | |
.mapError({ $0 as Error }) | |
.flatMap({ result -> AnyPublisher<T, Error> in | |
guard let urlResponse = result.response as? HTTPURLResponse, (200...299).contains(urlResponse.statusCode) else { | |
return Just(result.response) | |
.tryMap({ response in | |
if let urlResponse = response as? HTTPURLResponse { | |
let apiError = APIError(statusCode: urlResponse.statusCode) | |
throw apiError | |
} else { | |
throw APIError(statusCode: 0) | |
} | |
}).eraseToAnyPublisher() | |
} | |
return Just(result.data).decode(type: T.self, decoder: JSONDecoder()).eraseToAnyPublisher() | |
}) | |
.receive(on: DispatchQueue.main) | |
.eraseToAnyPublisher() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AppView.swift | |
// StalkForTwitter | |
// | |
// Created by Alperen Ünal on 4.06.2020. | |
// Copyright © 2020 Alperen Ünal. All rights reserved. | |
// | |
import SwiftUI | |
struct AppView: View { | |
init() { | |
UITabBar.appearance().barTintColor = UIColor(named: "BackgroundBlue") | |
} | |
var body: some View { | |
TabView { | |
InspectedView().tabItem { | |
Image(systemName: "eye") | |
Text("Inspected") | |
}.tag(0) | |
ProfileView().tabItem { | |
Image(systemName: "house") | |
Text("Profile") | |
}.tag(1) | |
MoreView().tabItem { | |
Image(systemName: "ellipsis") | |
Text("More") | |
}.tag(2) | |
} | |
.accentColor(.white) | |
} | |
} | |
struct AppView_Previews: PreviewProvider { | |
static var previews: some View { | |
AppView() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import PopupView | |
enum ContainedView { | |
case splash, auth, app | |
} | |
struct RootView: View { | |
@ObservedObject var rootVM = RootViewModel() | |
var body: some View { | |
ZStack { | |
containedView() | |
.transition(.slide) | |
} | |
.onAppear { | |
NotificationCenter.default.addObserver(forName: NSNotification.Name("signOut"), object: nil, queue: .main) { (_) in | |
self.rootVM.containedView = .auth | |
} | |
self.rootVM.checkIsAuth() | |
} | |
.popup(isPresented: $rootVM.protectedError, type: .`default`, closeOnTap: false) { | |
PopUpView(title: "Oops!", imageName: "protected_account", description: "To use this app, you must be having public account") { | |
self.rootVM.protectedError = false | |
self.rootVM.containedView = .auth | |
} | |
} | |
} | |
func containedView() -> AnyView { | |
switch rootVM.containedView { | |
case .splash: return AnyView(SplashView().id("splash")) | |
case .auth: return AnyView(AuthView().environmentObject(TwitterService()).id("auth")) | |
case .app: return AnyView(AppView().id("app")) | |
} | |
} | |
struct RootView_Previews: PreviewProvider { | |
static var previews: some View { | |
RootView() | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import FirebaseAuth | |
import Combine | |
import KeychainSwift | |
class RootViewModel: ObservableObject { | |
@Published var containedView: ContainedView = .splash | |
@Published var protectedError = false | |
var isError = false | |
var cancellables = Set<AnyCancellable>() | |
let apiService = APIService() | |
let keychain = KeychainSwift() | |
func checkIsAuth() { | |
if Auth.auth().currentUser == nil { | |
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { | |
withAnimation { | |
self.containedView = .auth | |
} | |
} | |
} else { | |
self.getUserInfo() | |
} | |
} | |
func getUserInfo() { | |
let userID = keychain.get("userId") ?? "" | |
Route.sharedInstance.urlComponent.path = Route.Path.getUserInfo.rawValue | |
Route.sharedInstance.urlComponent.queryItems = [ | |
URLQueryItem(name: "user_id", value: userID) | |
] | |
var urlRequest = URLRequest(url: Route.sharedInstance.urlComponent.url!) | |
urlRequest.addValue("Bearer \(BEARER_TOKEN)", forHTTPHeaderField: "authorization") | |
let publisher: AnyPublisher<User, Error> = apiService.fetchWithURLRequest(urlRequest) | |
publisher.sink(receiveCompletion: { (completion) in | |
if case .failure(let error) = completion, | |
let _ = error as? APIError { | |
self.containedView = .auth | |
} | |
}) { (user) in | |
CurrentUser.addCurrentUser(user: user) | |
withAnimation { | |
if !user.protected { | |
if !self.isError { | |
self.containedView = .app | |
} else { | |
self.containedView = .auth | |
} | |
} else { | |
self.protectedError = true | |
} | |
} | |
} | |
.store(in: &cancellables) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import FirebaseAuth | |
import Combine | |
import KeychainSwift | |
class RootViewModel: ObservableObject { | |
@Published var containedView: ContainedView = .splash | |
@Published var protectedError = false | |
var isError = false | |
var cancellables = Set<AnyCancellable>() | |
let apiService = APIService() | |
let keychain = KeychainSwift() | |
func checkIsAuth() { | |
if Auth.auth().currentUser == nil { | |
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { | |
withAnimation { | |
self.containedView = .auth | |
} | |
} | |
} else { | |
self.getUserInfo() | |
} | |
} | |
func getUserInfo() { | |
let userID = keychain.get("userId") ?? "" | |
Route.sharedInstance.urlComponent.path = Route.Path.getUserInfo.rawValue | |
Route.sharedInstance.urlComponent.queryItems = [ | |
URLQueryItem(name: "user_id", value: userID) | |
] | |
var urlRequest = URLRequest(url: Route.sharedInstance.urlComponent.url!) | |
urlRequest.addValue("Bearer \(BEARER_TOKEN)", forHTTPHeaderField: "authorization") | |
let publisher: AnyPublisher<User, Error> = apiService.fetchWithURLRequest(urlRequest) | |
publisher.sink(receiveCompletion: { (completion) in | |
if case .failure(let error) = completion, | |
let _ = error as? APIError { | |
self.containedView = .auth | |
} | |
}) { (user) in | |
CurrentUser.addCurrentUser(user: user) | |
withAnimation { | |
if !user.protected { | |
if !self.isError { | |
self.containedView = .app | |
} else { | |
self.containedView = .auth | |
} | |
} else { | |
self.protectedError = true | |
} | |
} | |
} | |
.store(in: &cancellables) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment