Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6f0fee3
- Installed RxSwift library
erfanwakka Feb 18, 2020
8fc5931
- Added base groups and redirect files
erfanwakka Feb 18, 2020
e625c98
- Add github logo and handleError helper function
erfanwakka Feb 18, 2020
d944cc4
- Implemented github Authorization
erfanwakka Feb 18, 2020
dade8dc
- Added test for testing Authorization
erfanwakka Feb 18, 2020
bf2518c
- Implemented directories and base of Repositories
erfanwakka Feb 18, 2020
f8a8f74
- Implemented userDefaults service to store token key
erfanwakka Feb 19, 2020
38963c7
- presenting searchController after saving token key
erfanwakka Feb 19, 2020
6c520f1
- Added search repositories urls and models
erfanwakka Feb 19, 2020
b8283d9
- Implemented repositories viewModel
erfanwakka Feb 19, 2020
6c00115
- Implemented search repositories UI and it's controller
erfanwakka Feb 19, 2020
515a734
- Added box for binding if needed
erfanwakka Feb 19, 2020
cb50ae5
- Added test file and project reqs
erfanwakka Feb 19, 2020
6ea3602
- navigate to repositories if it has token
erfanwakka Feb 19, 2020
a050cda
- Changed API error enum
erfanwakka Feb 19, 2020
0bc1a52
Merge branch 'feature/githubRepositories' into feature/githubAuthoriz…
erfanwakka Feb 19, 2020
0950157
- Added throttle and distinction on searchbar title
erfanwakka Feb 19, 2020
f8d3367
- Implemented directories and setup files
erfanwakka Feb 19, 2020
47d3d8f
- setup storyboard reference via authorization
erfanwakka Feb 19, 2020
2865084
- Added models and urls
erfanwakka Feb 19, 2020
0019e61
- implemented UI
erfanwakka Feb 19, 2020
f2f8368
- Implemented viewModel with getUser API
erfanwakka Feb 19, 2020
72efd17
- Attached UI components and fetch user profile
erfanwakka Feb 19, 2020
9e821c3
- Migrating Alamofire to v.5
erfanwakka Feb 20, 2020
e095a7e
- Implemented directories and setup files for commits
erfanwakka Feb 20, 2020
bfb06d7
- Implemented url and models
erfanwakka Feb 20, 2020
8fb7e38
- Implemented UI and storyboard
erfanwakka Feb 20, 2020
e018c70
- Implemented API call in viewModel
erfanwakka Feb 20, 2020
2ea4917
- Implemented viewController for commits
erfanwakka Feb 20, 2020
36eaa14
- navigate to commits via row select on repositories
erfanwakka Feb 20, 2020
9b765ac
- Fixed refreshcontrol not working bug
erfanwakka Feb 20, 2020
a945297
- Added tests for commits
erfanwakka Feb 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ target 'iOS-Challenge' do
use_frameworks!

pod 'Alamofire'
pod 'RxSwift', '~> 5'
pod 'RxCocoa', '~> 5'
# Pods for iOS-Challenge

target 'iOS-ChallengeTests' do
Expand Down
322 changes: 298 additions & 24 deletions iOS-Challenge.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

32 changes: 0 additions & 32 deletions iOS-Challenge/Alamofire+Decodable.swift

This file was deleted.

46 changes: 0 additions & 46 deletions iOS-Challenge/AppDelegate.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "download.png"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 0 additions & 65 deletions iOS-Challenge/Base.lproj/Main.storyboard

This file was deleted.

32 changes: 32 additions & 0 deletions iOS-Challenge/Modules/Authorization/Model/Authorization.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Authorization.swift
// iOS-Challenge
//
// Created by Erfan Andesta on 2/18/20.
// Copyright © 2020 Farshad Mousalou. All rights reserved.
//

import Foundation

struct Authorization {
static var parameters: [String: Any] = [
"client_id": clientId,
"redirect_uri": redirect_url,
"scope": "repo user",
"client_secret": clientSecret,
"state": 0
]
static func setCode(code: String) {
parameters["code"] = code
parameters["client_secret"] = clientSecret
parameters["scope"] = nil
}
static func resetCode() {
parameters["code"] = nil
parameters["client_secret"] = nil
parameters["scope"] = "repo user"
}
private static let clientId = "04860a64b85b7438bf91"
private static let clientSecret = "13342aaf3eb01b5498fc16b1bad90e1ab0e64a28"
private static let redirect_url = "challenge://app/callback"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// ViewController.swift
// iOS-Challenge
//
// Created by Farshad Mousalou on 1/28/20.
// Copyright © 2020 Farshad Mousalou. All rights reserved.
//

import UIKit
import Alamofire
import SafariServices

class AuthorizationViewController: UIViewController {

//MARK: - Actions -
@IBAction func loginDidPress(_ sender: Any?) {
viewModel.login { (result) in
switch result {
case .success(let url):
UIApplication.shared.open(url, options: [:], completionHandler: nil)
case .failure(let error):
handleError(error: error)
}
}
}
//MARK: - Vars -
var viewModel = AuthorizationViewModel()

//MARK: - View's LifeCycle -

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let _ = UserDefaultsService.shared.getToken() {
navigateToRepositories()
}
}

//MARK: - Functions -
func getAuthenticationCode(with code: String) {
viewModel.getAuthentication(with: code) { [weak self] (result) in
switch result {
case .success(let accessToken):
UserDefaultsService.shared.setToken(accessToken.accessToken)
self?.navigateToRepositories()
break
case .failure(let error):
self?.handleError(error: error)
}
}
}
fileprivate func navigateToRepositories() {
performSegue(withIdentifier: "presentTabbarController", sender: self)
}
}



Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// AuthorizationViewModel.swift
// iOS-Challenge
//
// Created by Erfan Andesta on 2/18/20.
// Copyright © 2020 Farshad Mousalou. All rights reserved.
//

import Foundation
import Alamofire

enum APIError: Error {
case failedRequest
case notURL
}
class AuthorizationViewModel {

//MARK: - Vars -

//MARK: - Functions -

func login(completionHandler: (Swift.Result<URL, Error>) -> Void) {
Authorization.resetCode()
guard let url = URL(string: URLs.authorizationURL), let requestURL = url.encodeURL(withUrl: url, withMethod: .get, withParameters: Authorization.parameters) else {
completionHandler(.failure(APIError.notURL))
return
}
completionHandler(.success(requestURL))
}
func getAuthentication(with code: String, completionHandler: @escaping (Swift.Result<AccessTokenResponse, Error>) -> Void) {

guard let url = URL(string: URLs.authorizationAccessCodeURL) else {
completionHandler(.failure(APIError.notURL))
return
}
Authorization.setCode(code: code)
AF.request(url, method: .post, parameters: Authorization.parameters, encoding: JSONEncoding.prettyPrinted, headers: ["Accept":"application/json"], interceptor: nil)
.validate()
.responseDecodable { (response: DataResponse<AccessTokenResponse, AFError>) in
switch response.result {
case .success(let accessToken):
completionHandler(.success(accessToken))
case .failure(let error):
completionHandler(.failure(error))
}
}
}
}
Loading