diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8af3431
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+# Xcode
+xcuserdata/
+project.xcworkspace/
+Pods/
\ No newline at end of file
diff --git a/Podfile b/Podfile
new file mode 100644
index 0000000..a00d849
--- /dev/null
+++ b/Podfile
@@ -0,0 +1,21 @@
+# Uncomment the next line to define a global platform for your project
+# platform :ios, '9.0'
+
+target 'mobile-coding-challenge' do
+ # Comment the next line if you don't want to use dynamic frameworks
+ use_frameworks!
+
+ # Pods for mobile-coding-challenge
+ pod 'Moya'
+ pod 'SwiftyJSON'
+ pod 'Kingfisher'
+
+end
+
+target 'mobile-coding-challenge-unit-tests' do
+ inherit! :search_paths
+
+ pod 'Moya'
+ pod 'SwiftyJSON'
+
+end
diff --git a/Podfile.lock b/Podfile.lock
new file mode 100644
index 0000000..6ed70c8
--- /dev/null
+++ b/Podfile.lock
@@ -0,0 +1,32 @@
+PODS:
+ - Alamofire (5.2.2)
+ - Kingfisher (5.15.0):
+ - Kingfisher/Core (= 5.15.0)
+ - Kingfisher/Core (5.15.0)
+ - Moya (14.0.0):
+ - Moya/Core (= 14.0.0)
+ - Moya/Core (14.0.0):
+ - Alamofire (~> 5.0)
+ - SwiftyJSON (5.0.0)
+
+DEPENDENCIES:
+ - Kingfisher
+ - Moya
+ - SwiftyJSON
+
+SPEC REPOS:
+ trunk:
+ - Alamofire
+ - Kingfisher
+ - Moya
+ - SwiftyJSON
+
+SPEC CHECKSUMS:
+ Alamofire: 814429acc853c6c54ff123fc3d2ef66803823ce0
+ Kingfisher: 1acb67597a520c2d0310677e66d6e0af455ef757
+ Moya: 5b45dacb75adb009f97fde91c204c1e565d31916
+ SwiftyJSON: 36413e04c44ee145039d332b4f4e2d3e8d6c4db7
+
+PODFILE CHECKSUM: 9a7dc13e8ed477ab04dc26d1d80a1fa72dece796
+
+COCOAPODS: 1.9.3
diff --git a/README.md b/README.md
index f83520b..b0d2b72 100644
--- a/README.md
+++ b/README.md
@@ -1,53 +1,18 @@
-# Mobile Coding Challenge
+# Mobile Coding Challenge by [Gemography](https://github.com/gemography)
-## Idea of the App
-The task is to implement a small app that will list the most starred Github repos that were created in the last 30 days.
-You'll be fetching the sorted JSON data directly from the Github API (Github API explained down below).
+## Idea of the App
-## Features
-* As a User I should be able to list the most starred Github repos that were created in the last 30 days.
-* As a User I should see the results as a list. One repository per row.
-* As a User I should be able to see for each repo/row the following details :
- * Repository name
- * Repository description
- * Numbers of stars for the repo.
- * Username and avatar of the owner.
-* [BONUS] As a User I should be able to keep scrolling and new results should appear (pagination).
+The task is just to implement a small app that will list the most starred Github repos that were created in the last 30 days.
-## Things to keep in mind 🚨
-* Features are less important than code quality. Put more focus on code quality and less on speed and number of features implemented.
-* Your code will be evaluated based on: code structure, programming best practices, legibility (and not number of features implemented or speed).
-* The git commit history (and git commit messages) will be also evaluated.
-* Do not forget to include few details about the project in the README (e.g explain choice of libraries, how to run it ...)
+## How to run the challenge project?
-## How to get the data from Github
-To get the most starred Github repos created in the last 30 days (relative to 2017-11-22), you'll need to call the following endpoint :
-
-`https://api.github.com/search/repositories?q=created:>2017-10-22&sort=stars&order=desc`
-
-The JSON data from Github will be paginated (you'll receive around 100 repos per JSON page).
-
-To get the 2nd page, you add `&page=2` to the end of your API request :
-
-`https://api.github.com/search/repositories?q=created:>2017-10-22&sort=stars&order=desc&page=2`
-
-To get the 3rd page, you add `&page=3` ... etc
-
-You can read more about the Github API over [here](https://developer.github.com/v3/search/#search-repositories
-).
-
-## Mockups
-
-
-Here's what each element represents :
-
-
-
-
-## Technologies to use
-Choose whatever mobile platform you're most familiar with.
-
-* For iOS, feel free to use Swift or Objective-C.
-* For Android, feel free to use Kotlin or Java.
+1. Clone this repo.
+2. Open shell window and navigate to project folder.
+3. Run
+```bash
+pod install
+```
+4. Open mobile-coding-challenge.xcworkspace and run the project on selected device or simulator.
+Good luck!
diff --git a/mobile-coding-challenge-unit-tests/Info.plist b/mobile-coding-challenge-unit-tests/Info.plist
new file mode 100644
index 0000000..64d65ca
--- /dev/null
+++ b/mobile-coding-challenge-unit-tests/Info.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+
+
diff --git a/mobile-coding-challenge-unit-tests/MostStarredGithubReposJSONTests.swift b/mobile-coding-challenge-unit-tests/MostStarredGithubReposJSONTests.swift
new file mode 100644
index 0000000..c6eef12
--- /dev/null
+++ b/mobile-coding-challenge-unit-tests/MostStarredGithubReposJSONTests.swift
@@ -0,0 +1,106 @@
+//
+// MostStarredGithubReposJSONTests.swift
+// mobile-coding-challenge-unit-tests
+//
+// Created by Mobile on 9/20/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import XCTest
+import Moya
+import SwiftyJSON
+
+class MostStarredGithubReposJSONTests: XCTestCase {
+
+ override func setUp() {
+ super.setUp()
+
+ self.continueAfterFailure = false
+
+ }
+
+ func testForIsTheMostStarredGithubReposJSONCorrect(){
+
+ let expectation = self.expectation(description: "theMostStarredGithubReposJSONExpectation")
+
+ var previousMonthDate: Date?
+
+ if let _previousMonthDate = Calendar.current.date(byAdding: .month, value: -1, to: Date()){
+
+ previousMonthDate = _previousMonthDate
+
+ let requestProvider = MoyaProvider()
+
+ requestProvider.request(.getMostGithubRepos(created_at: previousMonthDate!.formattedDate(using: "YYYY-MM-dd"), page: 1)) { result in
+
+ switch result {
+ case let .success(moyaResponse):
+
+ let responseJSON = JSON(moyaResponse.data)
+
+ var mostStarredGithubRepos: [JSON]?
+ var totalCount : Int?
+
+ if moyaResponse.statusCode == 200{
+
+ if let _mostStarredGithubRepos = responseJSON["items"].array{
+
+ if let _totalCount = responseJSON["total_count"].int{
+
+ mostStarredGithubRepos = _mostStarredGithubRepos
+
+ totalCount = _totalCount
+
+ var totalChecks: Int = 0
+
+ for _mostStarredGithubRepo in mostStarredGithubRepos!{
+
+ let mostStarredGithubRepo = GithubRepositoryEntity(from: _mostStarredGithubRepo)
+
+ XCTAssertNotNil(mostStarredGithubRepo, "TEST: IS THE MOST STARRED GITHUB REPOS JSON CORRECT => Response JSON is not fit : Something missed from GithubRepositoryEntity")
+
+ totalChecks += 1
+
+ }
+
+ XCTAssertEqual(totalChecks, mostStarredGithubRepos!.count)
+ expectation.fulfill()
+
+ return
+
+ }
+
+ XCTAssertNotNil(totalCount, "TEST: IS THE MOST STARRED GITHUB REPOS JSON CORRECT => Response JSON is not fit : (total_count => Int) is not exists or is not an integer.")
+
+ return
+
+ }
+
+ XCTAssertNotNil(mostStarredGithubRepos, "TEST: IS THE MOST STARRED GITHUB REPOS JSON CORRECT => Response JSON is not fit : [items] is not exists or is not an array.")
+
+ return
+
+ }
+
+ XCTAssertEqual(moyaResponse.statusCode, 200, "TEST: IS THE MOST STARRED GITHUB REPOS JSON CORRECT => Created_at is not fit")
+ expectation.fulfill()
+
+
+ default:
+ expectation.fulfill()
+
+ }
+
+ }
+
+ self.wait(for: [expectation], timeout: 10.0)
+
+ return
+
+ }
+
+ XCTAssertNotNil(previousMonthDate, "TEST: IS THE MOST STARRED GITHUB REPOS JSON CORRECT => Previous month date is incorrect")
+
+ }
+
+}
diff --git a/mobile-coding-challenge-unit-tests/ShortValueOfIntTests.swift b/mobile-coding-challenge-unit-tests/ShortValueOfIntTests.swift
new file mode 100644
index 0000000..238cef3
--- /dev/null
+++ b/mobile-coding-challenge-unit-tests/ShortValueOfIntTests.swift
@@ -0,0 +1,23 @@
+//
+// ShortValueOfIntTests.swift
+// mobile-coding-challenge-unit-tests
+//
+// Created by Mobile on 9/20/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import XCTest
+
+class ShortValueOfIntTests: XCTestCase {
+
+ func testForIsShortValueOfIntCorrect(){
+
+ XCTAssertEqual(100.shortValue, "100")
+ XCTAssertEqual((-800).shortValue, "-800")
+ XCTAssertEqual(8000.shortValue, "8.0K")
+ XCTAssertEqual(2000000.shortValue, "2.0M")
+ XCTAssertEqual(100000000000.shortValue, "+100...")
+
+ }
+
+}
diff --git a/mobile-coding-challenge.xcodeproj/project.pbxproj b/mobile-coding-challenge.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..2c58ea2
--- /dev/null
+++ b/mobile-coding-challenge.xcodeproj/project.pbxproj
@@ -0,0 +1,673 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 51;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 75620E3B2516548300F87394 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E3A2516548300F87394 /* AppDelegate.swift */; };
+ 75620E442516548700F87394 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 75620E432516548700F87394 /* Assets.xcassets */; };
+ 75620E472516548700F87394 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75620E452516548700F87394 /* LaunchScreen.storyboard */; };
+ 75620E54251655E400F87394 /* MostStarredGithubReposProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E53251655E400F87394 /* MostStarredGithubReposProtocol.swift */; };
+ 75620E5F251659B700F87394 /* BaseUINavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E5E251659B700F87394 /* BaseUINavigationController.swift */; };
+ 75620E63251660A000F87394 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 75620E62251660A000F87394 /* Localizable.strings */; };
+ 75620E6825166EB800F87394 /* UIViewController + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E6725166EB800F87394 /* UIViewController + Extension.swift */; };
+ 75620E6925166F1300F87394 /* MostStarredGithubReposPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E572516561800F87394 /* MostStarredGithubReposPresenter.swift */; };
+ 75620E6A25166F8B00F87394 /* MostStarredGithubReposView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E51251655D000F87394 /* MostStarredGithubReposView.swift */; };
+ 75620E6B25166FE300F87394 /* MostStarredGithubReposUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E4F251655BC00F87394 /* MostStarredGithubReposUI.swift */; };
+ 75620E6C251670E400F87394 /* MostStarredGithubReposRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E5B2516563100F87394 /* MostStarredGithubReposRouter.swift */; };
+ 75620E6D2516719900F87394 /* MostStarredGithubReposTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E602516602900F87394 /* MostStarredGithubReposTableViewCell.swift */; };
+ 75620E6E251671BF00F87394 /* MostStarredGithubReposInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E55251655FF00F87394 /* MostStarredGithubReposInteractor.swift */; };
+ 75620E70251677C200F87394 /* MostStarredGithubReposEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E592516562600F87394 /* MostStarredGithubReposEntity.swift */; };
+ 75620E722516895A00F87394 /* Int + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E712516895A00F87394 /* Int + Extension.swift */; };
+ 75620E742516987F00F87394 /* String + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E732516987F00F87394 /* String + Extension.swift */; };
+ 75620E772516A8B800F87394 /* RequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E762516A8B800F87394 /* RequestHandler.swift */; };
+ 75620E7A2516B5DF00F87394 /* Date + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E782516B58B00F87394 /* Date + Extension.swift */; };
+ 7572ADA625175C2500C8679A /* ShortValueOfIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7572ADA525175C2500C8679A /* ShortValueOfIntTests.swift */; };
+ 7572ADA725175CBD00C8679A /* Int + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E712516895A00F87394 /* Int + Extension.swift */; };
+ 7572ADA925175DA000C8679A /* MostStarredGithubReposJSONTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7572ADA825175DA000C8679A /* MostStarredGithubReposJSONTests.swift */; };
+ 7572ADAA25175F2800C8679A /* MostStarredGithubReposEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E592516562600F87394 /* MostStarredGithubReposEntity.swift */; };
+ 7572ADAB25175F3400C8679A /* RequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E762516A8B800F87394 /* RequestHandler.swift */; };
+ 7572ADAC251760B700C8679A /* Date + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75620E782516B58B00F87394 /* Date + Extension.swift */; };
+ 7F2954C3013C6DFD1EB57D67 /* Pods_mobile_coding_challenge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F57D743DE22E5A3A3F84BF3F /* Pods_mobile_coding_challenge.framework */; };
+ A01CAA4FF1F4C7C6B5E2D638 /* libPods-mobile-coding-challenge-unit-tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F66A9D032FA7F46C709E77 /* libPods-mobile-coding-challenge-unit-tests.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 7572ADA025175BAF00C8679A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 75620E2F2516548300F87394 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 75620E362516548300F87394;
+ remoteInfo = "mobile-coding-challenge";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 0F01CB3D02F0E5BDDFE0704F /* Pods-mobile-coding-challenge.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mobile-coding-challenge.debug.xcconfig"; path = "Target Support Files/Pods-mobile-coding-challenge/Pods-mobile-coding-challenge.debug.xcconfig"; sourceTree = ""; };
+ 4D18A88125FC096583B5DE6D /* Pods-mobile-coding-challenge.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mobile-coding-challenge.release.xcconfig"; path = "Target Support Files/Pods-mobile-coding-challenge/Pods-mobile-coding-challenge.release.xcconfig"; sourceTree = ""; };
+ 51F66A9D032FA7F46C709E77 /* libPods-mobile-coding-challenge-unit-tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-mobile-coding-challenge-unit-tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 75620E372516548300F87394 /* mobile-coding-challenge.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "mobile-coding-challenge.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 75620E3A2516548300F87394 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 75620E432516548700F87394 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 75620E462516548700F87394 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 75620E482516548700F87394 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 75620E4F251655BC00F87394 /* MostStarredGithubReposUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposUI.swift; sourceTree = ""; };
+ 75620E51251655D000F87394 /* MostStarredGithubReposView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposView.swift; sourceTree = ""; };
+ 75620E53251655E400F87394 /* MostStarredGithubReposProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposProtocol.swift; sourceTree = ""; };
+ 75620E55251655FF00F87394 /* MostStarredGithubReposInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposInteractor.swift; sourceTree = ""; };
+ 75620E572516561800F87394 /* MostStarredGithubReposPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposPresenter.swift; sourceTree = ""; };
+ 75620E592516562600F87394 /* MostStarredGithubReposEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposEntity.swift; sourceTree = ""; };
+ 75620E5B2516563100F87394 /* MostStarredGithubReposRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposRouter.swift; sourceTree = ""; };
+ 75620E5E251659B700F87394 /* BaseUINavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseUINavigationController.swift; sourceTree = ""; };
+ 75620E602516602900F87394 /* MostStarredGithubReposTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposTableViewCell.swift; sourceTree = ""; };
+ 75620E62251660A000F87394 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; };
+ 75620E6725166EB800F87394 /* UIViewController + Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController + Extension.swift"; sourceTree = ""; };
+ 75620E712516895A00F87394 /* Int + Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int + Extension.swift"; sourceTree = ""; };
+ 75620E732516987F00F87394 /* String + Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String + Extension.swift"; sourceTree = ""; };
+ 75620E762516A8B800F87394 /* RequestHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestHandler.swift; sourceTree = ""; };
+ 75620E782516B58B00F87394 /* Date + Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date + Extension.swift"; sourceTree = ""; };
+ 7572AD9B25175BAF00C8679A /* mobile-coding-challenge-unit-tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "mobile-coding-challenge-unit-tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 7572AD9F25175BAF00C8679A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 7572ADA525175C2500C8679A /* ShortValueOfIntTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortValueOfIntTests.swift; sourceTree = ""; };
+ 7572ADA825175DA000C8679A /* MostStarredGithubReposJSONTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MostStarredGithubReposJSONTests.swift; sourceTree = ""; };
+ A1A46AEB5C91E0ACBF4B1D5F /* Pods-mobile-coding-challenge-unit-tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mobile-coding-challenge-unit-tests.debug.xcconfig"; path = "Target Support Files/Pods-mobile-coding-challenge-unit-tests/Pods-mobile-coding-challenge-unit-tests.debug.xcconfig"; sourceTree = ""; };
+ C1CF037D9590E1CA8CBFC052 /* Pods-mobile-coding-challenge-unit-tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mobile-coding-challenge-unit-tests.release.xcconfig"; path = "Target Support Files/Pods-mobile-coding-challenge-unit-tests/Pods-mobile-coding-challenge-unit-tests.release.xcconfig"; sourceTree = ""; };
+ F57D743DE22E5A3A3F84BF3F /* Pods_mobile_coding_challenge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_mobile_coding_challenge.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 75620E342516548300F87394 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 7F2954C3013C6DFD1EB57D67 /* Pods_mobile_coding_challenge.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 7572AD9825175BAF00C8679A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A01CAA4FF1F4C7C6B5E2D638 /* libPods-mobile-coding-challenge-unit-tests.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 75620E2E2516548300F87394 = {
+ isa = PBXGroup;
+ children = (
+ 75620E392516548300F87394 /* mobile-coding-challenge */,
+ 7572AD9C25175BAF00C8679A /* mobile-coding-challenge-unit-tests */,
+ 75620E382516548300F87394 /* Products */,
+ 958ADBB33EB7D44312ABB616 /* Pods */,
+ AC28514262F839DE19CD30B2 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 75620E382516548300F87394 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 75620E372516548300F87394 /* mobile-coding-challenge.app */,
+ 7572AD9B25175BAF00C8679A /* mobile-coding-challenge-unit-tests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 75620E392516548300F87394 /* mobile-coding-challenge */ = {
+ isa = PBXGroup;
+ children = (
+ 75620E64251660A800F87394 /* Localizable Files */,
+ 75620E6625166E8D00F87394 /* Controllers */,
+ 75620E6525166E7A00F87394 /* Extensions */,
+ 75620E752516A8A500F87394 /* Helpers */,
+ 75620E3A2516548300F87394 /* AppDelegate.swift */,
+ 75620E432516548700F87394 /* Assets.xcassets */,
+ 75620E452516548700F87394 /* LaunchScreen.storyboard */,
+ 75620E482516548700F87394 /* Info.plist */,
+ );
+ path = "mobile-coding-challenge";
+ sourceTree = "";
+ };
+ 75620E4E2516557900F87394 /* Most Starred Github Repos */ = {
+ isa = PBXGroup;
+ children = (
+ 75620E4F251655BC00F87394 /* MostStarredGithubReposUI.swift */,
+ 75620E602516602900F87394 /* MostStarredGithubReposTableViewCell.swift */,
+ 75620E51251655D000F87394 /* MostStarredGithubReposView.swift */,
+ 75620E53251655E400F87394 /* MostStarredGithubReposProtocol.swift */,
+ 75620E55251655FF00F87394 /* MostStarredGithubReposInteractor.swift */,
+ 75620E572516561800F87394 /* MostStarredGithubReposPresenter.swift */,
+ 75620E592516562600F87394 /* MostStarredGithubReposEntity.swift */,
+ 75620E5B2516563100F87394 /* MostStarredGithubReposRouter.swift */,
+ );
+ path = "Most Starred Github Repos";
+ sourceTree = "";
+ };
+ 75620E5D2516597800F87394 /* Base Controllers */ = {
+ isa = PBXGroup;
+ children = (
+ 75620E5E251659B700F87394 /* BaseUINavigationController.swift */,
+ );
+ path = "Base Controllers";
+ sourceTree = "";
+ };
+ 75620E64251660A800F87394 /* Localizable Files */ = {
+ isa = PBXGroup;
+ children = (
+ 75620E62251660A000F87394 /* Localizable.strings */,
+ );
+ path = "Localizable Files";
+ sourceTree = "";
+ };
+ 75620E6525166E7A00F87394 /* Extensions */ = {
+ isa = PBXGroup;
+ children = (
+ 75620E6725166EB800F87394 /* UIViewController + Extension.swift */,
+ 75620E712516895A00F87394 /* Int + Extension.swift */,
+ 75620E732516987F00F87394 /* String + Extension.swift */,
+ 75620E782516B58B00F87394 /* Date + Extension.swift */,
+ );
+ path = Extensions;
+ sourceTree = "";
+ };
+ 75620E6625166E8D00F87394 /* Controllers */ = {
+ isa = PBXGroup;
+ children = (
+ 75620E5D2516597800F87394 /* Base Controllers */,
+ 75620E4E2516557900F87394 /* Most Starred Github Repos */,
+ );
+ path = Controllers;
+ sourceTree = "";
+ };
+ 75620E752516A8A500F87394 /* Helpers */ = {
+ isa = PBXGroup;
+ children = (
+ 75620E762516A8B800F87394 /* RequestHandler.swift */,
+ );
+ path = Helpers;
+ sourceTree = "";
+ };
+ 7572AD9C25175BAF00C8679A /* mobile-coding-challenge-unit-tests */ = {
+ isa = PBXGroup;
+ children = (
+ 7572ADA825175DA000C8679A /* MostStarredGithubReposJSONTests.swift */,
+ 7572ADA525175C2500C8679A /* ShortValueOfIntTests.swift */,
+ 7572AD9F25175BAF00C8679A /* Info.plist */,
+ );
+ path = "mobile-coding-challenge-unit-tests";
+ sourceTree = "";
+ };
+ 958ADBB33EB7D44312ABB616 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 0F01CB3D02F0E5BDDFE0704F /* Pods-mobile-coding-challenge.debug.xcconfig */,
+ 4D18A88125FC096583B5DE6D /* Pods-mobile-coding-challenge.release.xcconfig */,
+ A1A46AEB5C91E0ACBF4B1D5F /* Pods-mobile-coding-challenge-unit-tests.debug.xcconfig */,
+ C1CF037D9590E1CA8CBFC052 /* Pods-mobile-coding-challenge-unit-tests.release.xcconfig */,
+ );
+ path = Pods;
+ sourceTree = "";
+ };
+ AC28514262F839DE19CD30B2 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ F57D743DE22E5A3A3F84BF3F /* Pods_mobile_coding_challenge.framework */,
+ 51F66A9D032FA7F46C709E77 /* libPods-mobile-coding-challenge-unit-tests.a */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 75620E362516548300F87394 /* mobile-coding-challenge */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 75620E4B2516548700F87394 /* Build configuration list for PBXNativeTarget "mobile-coding-challenge" */;
+ buildPhases = (
+ B02EBC2749D9FC5BBDB2C878 /* [CP] Check Pods Manifest.lock */,
+ 75620E332516548300F87394 /* Sources */,
+ 75620E342516548300F87394 /* Frameworks */,
+ 75620E352516548300F87394 /* Resources */,
+ 47EB194D8AC28AD0E4900581 /* [CP] Embed Pods Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "mobile-coding-challenge";
+ productName = "mobile-coding-challenge";
+ productReference = 75620E372516548300F87394 /* mobile-coding-challenge.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 7572AD9A25175BAF00C8679A /* mobile-coding-challenge-unit-tests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 7572ADA425175BAF00C8679A /* Build configuration list for PBXNativeTarget "mobile-coding-challenge-unit-tests" */;
+ buildPhases = (
+ DAD24B4F7197FA6D4240AF37 /* [CP] Check Pods Manifest.lock */,
+ 7572AD9725175BAF00C8679A /* Sources */,
+ 7572AD9825175BAF00C8679A /* Frameworks */,
+ 7572AD9925175BAF00C8679A /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 7572ADA125175BAF00C8679A /* PBXTargetDependency */,
+ );
+ name = "mobile-coding-challenge-unit-tests";
+ productName = "mobile-coding-challenge-unit-tests";
+ productReference = 7572AD9B25175BAF00C8679A /* mobile-coding-challenge-unit-tests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 75620E2F2516548300F87394 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 1170;
+ LastUpgradeCheck = 1170;
+ ORGANIZATIONNAME = Zakariae;
+ TargetAttributes = {
+ 75620E362516548300F87394 = {
+ CreatedOnToolsVersion = 11.7;
+ };
+ 7572AD9A25175BAF00C8679A = {
+ CreatedOnToolsVersion = 11.7;
+ TestTargetID = 75620E362516548300F87394;
+ };
+ };
+ };
+ buildConfigurationList = 75620E322516548300F87394 /* Build configuration list for PBXProject "mobile-coding-challenge" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 75620E2E2516548300F87394;
+ productRefGroup = 75620E382516548300F87394 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 75620E362516548300F87394 /* mobile-coding-challenge */,
+ 7572AD9A25175BAF00C8679A /* mobile-coding-challenge-unit-tests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 75620E352516548300F87394 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 75620E472516548700F87394 /* LaunchScreen.storyboard in Resources */,
+ 75620E63251660A000F87394 /* Localizable.strings in Resources */,
+ 75620E442516548700F87394 /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 7572AD9925175BAF00C8679A /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 47EB194D8AC28AD0E4900581 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-mobile-coding-challenge/Pods-mobile-coding-challenge-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-mobile-coding-challenge/Pods-mobile-coding-challenge-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-mobile-coding-challenge/Pods-mobile-coding-challenge-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ B02EBC2749D9FC5BBDB2C878 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-mobile-coding-challenge-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ DAD24B4F7197FA6D4240AF37 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-mobile-coding-challenge-unit-tests-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 75620E332516548300F87394 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 75620E772516A8B800F87394 /* RequestHandler.swift in Sources */,
+ 75620E6C251670E400F87394 /* MostStarredGithubReposRouter.swift in Sources */,
+ 75620E70251677C200F87394 /* MostStarredGithubReposEntity.swift in Sources */,
+ 75620E6825166EB800F87394 /* UIViewController + Extension.swift in Sources */,
+ 75620E54251655E400F87394 /* MostStarredGithubReposProtocol.swift in Sources */,
+ 75620E5F251659B700F87394 /* BaseUINavigationController.swift in Sources */,
+ 75620E6B25166FE300F87394 /* MostStarredGithubReposUI.swift in Sources */,
+ 75620E6E251671BF00F87394 /* MostStarredGithubReposInteractor.swift in Sources */,
+ 75620E7A2516B5DF00F87394 /* Date + Extension.swift in Sources */,
+ 75620E722516895A00F87394 /* Int + Extension.swift in Sources */,
+ 75620E6925166F1300F87394 /* MostStarredGithubReposPresenter.swift in Sources */,
+ 75620E3B2516548300F87394 /* AppDelegate.swift in Sources */,
+ 75620E742516987F00F87394 /* String + Extension.swift in Sources */,
+ 75620E6D2516719900F87394 /* MostStarredGithubReposTableViewCell.swift in Sources */,
+ 75620E6A25166F8B00F87394 /* MostStarredGithubReposView.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 7572AD9725175BAF00C8679A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 7572ADA625175C2500C8679A /* ShortValueOfIntTests.swift in Sources */,
+ 7572ADAB25175F3400C8679A /* RequestHandler.swift in Sources */,
+ 7572ADA725175CBD00C8679A /* Int + Extension.swift in Sources */,
+ 7572ADAA25175F2800C8679A /* MostStarredGithubReposEntity.swift in Sources */,
+ 7572ADA925175DA000C8679A /* MostStarredGithubReposJSONTests.swift in Sources */,
+ 7572ADAC251760B700C8679A /* Date + Extension.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 7572ADA125175BAF00C8679A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 75620E362516548300F87394 /* mobile-coding-challenge */;
+ targetProxy = 7572ADA025175BAF00C8679A /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 75620E452516548700F87394 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 75620E462516548700F87394 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 75620E492516548700F87394 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ 75620E4A2516548700F87394 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 75620E4C2516548700F87394 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 0F01CB3D02F0E5BDDFE0704F /* Pods-mobile-coding-challenge.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = "mobile-coding-challenge/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "com.zakariae.mobile-coding-challenge";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 75620E4D2516548700F87394 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 4D18A88125FC096583B5DE6D /* Pods-mobile-coding-challenge.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = "mobile-coding-challenge/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "com.zakariae.mobile-coding-challenge";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 7572ADA225175BAF00C8679A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = A1A46AEB5C91E0ACBF4B1D5F /* Pods-mobile-coding-challenge-unit-tests.debug.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = "mobile-coding-challenge-unit-tests/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 13.7;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "com.zakariae.mobile-coding-challenge-unit-tests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/mobile-coding-challenge.app/mobile-coding-challenge";
+ };
+ name = Debug;
+ };
+ 7572ADA325175BAF00C8679A /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C1CF037D9590E1CA8CBFC052 /* Pods-mobile-coding-challenge-unit-tests.release.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = "mobile-coding-challenge-unit-tests/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 13.7;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "com.zakariae.mobile-coding-challenge-unit-tests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/mobile-coding-challenge.app/mobile-coding-challenge";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 75620E322516548300F87394 /* Build configuration list for PBXProject "mobile-coding-challenge" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 75620E492516548700F87394 /* Debug */,
+ 75620E4A2516548700F87394 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 75620E4B2516548700F87394 /* Build configuration list for PBXNativeTarget "mobile-coding-challenge" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 75620E4C2516548700F87394 /* Debug */,
+ 75620E4D2516548700F87394 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 7572ADA425175BAF00C8679A /* Build configuration list for PBXNativeTarget "mobile-coding-challenge-unit-tests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 7572ADA225175BAF00C8679A /* Debug */,
+ 7572ADA325175BAF00C8679A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 75620E2F2516548300F87394 /* Project object */;
+}
diff --git a/mobile-coding-challenge.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/mobile-coding-challenge.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..dcb467b
--- /dev/null
+++ b/mobile-coding-challenge.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/mobile-coding-challenge.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/mobile-coding-challenge.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/mobile-coding-challenge.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/mobile-coding-challenge.xcodeproj/xcuserdata/mobile.xcuserdatad/xcschemes/xcschememanagement.plist b/mobile-coding-challenge.xcodeproj/xcuserdata/mobile.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..4ce5fd5
--- /dev/null
+++ b/mobile-coding-challenge.xcodeproj/xcuserdata/mobile.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,14 @@
+
+
+
+
+ SchemeUserState
+
+ mobile-coding-challenge.xcscheme_^#shared#^_
+
+ orderHint
+ 9
+
+
+
+
diff --git a/mobile-coding-challenge.xcworkspace/contents.xcworkspacedata b/mobile-coding-challenge.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..e521183
--- /dev/null
+++ b/mobile-coding-challenge.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/mobile-coding-challenge.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/mobile-coding-challenge.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/mobile-coding-challenge.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/mobile-coding-challenge.xcworkspace/xcuserdata/mobile.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/mobile-coding-challenge.xcworkspace/xcuserdata/mobile.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
new file mode 100644
index 0000000..c7cb89f
--- /dev/null
+++ b/mobile-coding-challenge.xcworkspace/xcuserdata/mobile.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -0,0 +1,6 @@
+
+
+
diff --git a/mobile-coding-challenge/AppDelegate.swift b/mobile-coding-challenge/AppDelegate.swift
new file mode 100644
index 0000000..58ce5e3
--- /dev/null
+++ b/mobile-coding-challenge/AppDelegate.swift
@@ -0,0 +1,37 @@
+//
+// AppDelegate.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import UIKit
+import Kingfisher
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+
+ self.window = UIWindow(frame: UIScreen.main.bounds)
+ self.window?.rootViewController = BaseUINavigationController(rootViewController: MostStarredGithubReposRouter.createModule())
+ self.window?.makeKeyAndVisible()
+
+ self.clearKFCache()
+
+ return true
+
+ }
+
+ private func clearKFCache(){
+ KingfisherManager.shared.cache.clearMemoryCache()
+ KingfisherManager.shared.cache.clearDiskCache()
+ KingfisherManager.shared.cache.cleanExpiredDiskCache()
+ }
+
+
+}
+
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/100.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/100.png
new file mode 100644
index 0000000..b75a015
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/100.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/1024.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/1024.png
new file mode 100644
index 0000000..e623c74
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/1024.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/114.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/114.png
new file mode 100644
index 0000000..23f3a46
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/114.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/120.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/120.png
new file mode 100644
index 0000000..a2ec2e8
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/120.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/144.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/144.png
new file mode 100644
index 0000000..b211ff8
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/144.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/152.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/152.png
new file mode 100644
index 0000000..a60a3c1
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/152.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/167.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/167.png
new file mode 100644
index 0000000..0ec7c22
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/167.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/180.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/180.png
new file mode 100644
index 0000000..d63898c
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/180.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/20.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/20.png
new file mode 100644
index 0000000..667c064
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/20.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/29.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/29.png
new file mode 100644
index 0000000..b9e8675
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/29.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/40.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/40.png
new file mode 100644
index 0000000..8f055af
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/40.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/50.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/50.png
new file mode 100644
index 0000000..cce72c2
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/50.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/57.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/57.png
new file mode 100644
index 0000000..02ef1ab
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/57.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/58.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/58.png
new file mode 100644
index 0000000..3e0fe58
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/58.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/60.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/60.png
new file mode 100644
index 0000000..4f14b8f
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/60.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/72.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/72.png
new file mode 100644
index 0000000..86ef20b
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/72.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/76.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/76.png
new file mode 100644
index 0000000..8a34963
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/76.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/80.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/80.png
new file mode 100644
index 0000000..dc72c45
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/80.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/87.png b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/87.png
new file mode 100644
index 0000000..b47c4b2
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/87.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/Contents.json b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..65b74d7
--- /dev/null
+++ b/mobile-coding-challenge/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1 @@
+{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"}]}
\ No newline at end of file
diff --git a/mobile-coding-challenge/Assets.xcassets/Contents.json b/mobile-coding-challenge/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/mobile-coding-challenge/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/Contents.json b/mobile-coding-challenge/Assets.xcassets/Icons/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/mobile-coding-challenge/Assets.xcassets/Icons/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/Contents.json b/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/Contents.json
new file mode 100644
index 0000000..3e723af
--- /dev/null
+++ b/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "empty-avatar-icon.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "empty-avatar-icon@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "empty-avatar-icon@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon.png b/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon.png
new file mode 100644
index 0000000..72edda8
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon@2x.png b/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon@2x.png
new file mode 100644
index 0000000..6627c25
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon@2x.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon@3x.png b/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon@3x.png
new file mode 100644
index 0000000..d4a4d5d
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/Icons/empty-avatar-icon.imageset/empty-avatar-icon@3x.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/Contents.json b/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/Contents.json
new file mode 100644
index 0000000..1c9348d
--- /dev/null
+++ b/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "filename" : "star_icon.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "star_icon@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "star_icon@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon.png b/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon.png
new file mode 100644
index 0000000..89e8daf
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon@2x.png b/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon@2x.png
new file mode 100644
index 0000000..c14cc8a
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon@2x.png differ
diff --git a/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon@3x.png b/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon@3x.png
new file mode 100644
index 0000000..f76a329
Binary files /dev/null and b/mobile-coding-challenge/Assets.xcassets/Icons/star_icon.imageset/star_icon@3x.png differ
diff --git a/mobile-coding-challenge/Base.lproj/LaunchScreen.storyboard b/mobile-coding-challenge/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..865e932
--- /dev/null
+++ b/mobile-coding-challenge/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile-coding-challenge/Controllers/Base Controllers/BaseUINavigationController.swift b/mobile-coding-challenge/Controllers/Base Controllers/BaseUINavigationController.swift
new file mode 100644
index 0000000..1dfb9e1
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Base Controllers/BaseUINavigationController.swift
@@ -0,0 +1,20 @@
+//
+// BaseUINavigationController.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import UIKit
+
+class BaseUINavigationController: UINavigationController {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ self.view.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposEntity.swift b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposEntity.swift
new file mode 100644
index 0000000..71ec1aa
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposEntity.swift
@@ -0,0 +1,83 @@
+//
+// MostStarredGithubReposEntity.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import Foundation
+import SwiftyJSON
+
+class GithubRepositoryEntity{
+
+ private var id : Int!
+ private var name : String!
+ private var description : String?
+ private var ownerImageLink : String?
+ private var ownerName : String!
+ private var numberOfStars : Int!
+ private var shortNumberOfStars: String?
+
+ func getId() -> Int{ return self.id }
+
+ func getName()->String{ return self.name }
+
+ func getDescription()->String{ return self.description ?? "" }
+
+ func getOwnerImageURL()->URL?{
+ if let imageURL = URL(string: self.ownerImageLink ?? ""){
+ return imageURL
+ }
+ return nil
+ }
+
+ func getOwnerName()->String{ return self.ownerName }
+
+ func getNumberOfStars()->Int{ return self.numberOfStars }
+
+ func getShortNumberOfStars()->String{ return self.shortNumberOfStars ?? "" }
+
+ private func setNumberOfStars(numberOfStars: Int){
+
+ self.numberOfStars = numberOfStars
+ self.shortNumberOfStars = numberOfStars.shortValue
+
+ }
+
+}
+
+extension GithubRepositoryEntity{
+
+ convenience init?(from repoJSON: JSON){
+ self.init()
+
+ let ownerObject = repoJSON["owner"].dictionaryObject
+
+ if let repoId = repoJSON["id"].int,
+ let repoName = repoJSON["name"].string,
+ let ownerName = ownerObject?["login"] as? String,
+ let numberOfStars = repoJSON["stargazers_count"].int{
+
+ self.id = repoId
+ self.name = repoName
+ self.ownerName = ownerName
+ self.setNumberOfStars(numberOfStars: numberOfStars)
+
+ if let description = repoJSON["description"].string{
+ self.description = description
+ }
+
+ if let avatarStringURL = ownerObject?["avatar_url"] as? String{
+ self.ownerImageLink = avatarStringURL
+ }
+
+ return
+
+ }
+
+ return nil
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposInteractor.swift b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposInteractor.swift
new file mode 100644
index 0000000..14ac46b
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposInteractor.swift
@@ -0,0 +1,69 @@
+//
+// MostStarredGithubReposInteractor.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import Moya
+import SwiftyJSON
+
+class MostStarredGithubReposInteractor: PresenterToMostStarredGithubReposInteractorProtocol{
+
+ var presenter: InteractorToMostStarredGithubReposPresenterProtocol!
+
+ func getMostStarredGithubRepos(from page: Int, isToUsePullRefresh: Bool) {
+
+ let requestHandler = MoyaProvider()
+
+ if let previousMonthDate = Calendar.current.date(byAdding: .month, value: -1, to: Date()){
+
+ requestHandler.request(.getMostGithubRepos(created_at: previousMonthDate.formattedDate(using: "YYYY-MM-dd"), page: page)){ result in
+
+ switch result {
+ case let .success(moyaResponse):
+
+ let responseJSON = JSON(moyaResponse.data)
+
+ var mostStarredGithubRepos: [GithubRepositoryEntity] = []
+ var totalCount: Int = 0
+
+ if let _mostStarredGithubRepos = responseJSON["items"].array,
+ let _totalCount = responseJSON["total_count"].int{
+
+ totalCount = _totalCount
+
+ for _mostStarredGithubRepo in _mostStarredGithubRepos{
+
+ if let mostStarredGithubRepo = GithubRepositoryEntity(from: _mostStarredGithubRepo){
+
+ mostStarredGithubRepos.append(mostStarredGithubRepo)
+
+ }
+
+ }
+
+ }
+
+ self.presenter.mostStarredGithubReposSuccessFetch(repos: mostStarredGithubRepos, isToUsePullRefresh: isToUsePullRefresh, totalCount: totalCount)
+
+
+ default:
+
+ self.presenter.mostStarredGithubReposSuccessFailure()
+
+ }
+
+ }
+
+ return
+
+ }
+
+ self.presenter.mostStarredGithubReposSuccessFailure()
+
+ }
+
+
+}
diff --git a/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposPresenter.swift b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposPresenter.swift
new file mode 100644
index 0000000..896f848
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposPresenter.swift
@@ -0,0 +1,63 @@
+//
+// MostStarredGithubReposPresenter.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import Foundation
+class MostStarredGithubReposPresenter: ViewToMostStarredGithubReposPresenterProtocol, InteractorToMostStarredGithubReposPresenterProtocol{
+
+ weak var view: PresenterToMostStarredGithubReposViewProtocol!
+ var interactor: PresenterToMostStarredGithubReposInteractorProtocol!
+ var router: PresenterToMostStarredGithubReposRouterProtocol!
+ var mostStarredGithubRepos: [GithubRepositoryEntity]! = []
+
+ var numberOfRows: Int!{
+ return self.mostStarredGithubRepos.count
+ }
+ var totalNumberOfMostStarredGithubRepos: Int! = -1
+ var activePage: Int! = 1
+
+ convenience init(view: PresenterToMostStarredGithubReposViewProtocol, interactor: PresenterToMostStarredGithubReposInteractorProtocol, router: PresenterToMostStarredGithubReposRouterProtocol) {
+ self.init()
+
+ self.view = view
+ self.interactor = interactor
+ self.router = router
+
+ }
+
+ func viewDidLoad() {
+
+ self.mostStarredGithubRepos = []
+ self.view.showLoader()
+ self.interactor.getMostStarredGithubRepos(from: self.activePage, isToUsePullRefresh: false)
+
+ }
+
+ func mostStarredGithubReposSuccessFetch(repos: [GithubRepositoryEntity], isToUsePullRefresh: Bool, totalCount: Int) {
+
+ self.totalNumberOfMostStarredGithubRepos = totalCount
+
+ if isToUsePullRefresh{
+ self.mostStarredGithubRepos = repos
+ }else{
+ self.mostStarredGithubRepos.append(contentsOf: repos)
+ self.activePage += 1
+ }
+
+ self.view.hideLoader()
+ self.view.reloadData()
+
+ }
+
+ func mostStarredGithubReposSuccessFailure() {
+
+ self.view.hideLoader()
+ self.view.showResponseError()
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposProtocol.swift b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposProtocol.swift
new file mode 100644
index 0000000..1e3386d
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposProtocol.swift
@@ -0,0 +1,43 @@
+//
+// MostStarredGithubReposProtocol.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import UIKit
+
+protocol PresenterToMostStarredGithubReposViewProtocol: class{
+ var presenter: ViewToMostStarredGithubReposPresenterProtocol! { get set }
+ func showLoader()
+ func hideLoader()
+ func showResponseError()
+ func reloadData()
+ func refreshMostStarredGithubReposData()
+}
+
+protocol ViewToMostStarredGithubReposPresenterProtocol{
+ var view: PresenterToMostStarredGithubReposViewProtocol! { get set }
+ var interactor: PresenterToMostStarredGithubReposInteractorProtocol! { get set }
+ var router: PresenterToMostStarredGithubReposRouterProtocol! { get set }
+ var mostStarredGithubRepos: [GithubRepositoryEntity]! { get set }
+ var numberOfRows: Int! { get }
+ var totalNumberOfMostStarredGithubRepos: Int! { get set }
+ var activePage: Int! { get set }
+ func viewDidLoad()
+}
+
+protocol PresenterToMostStarredGithubReposInteractorProtocol{
+ var presenter: InteractorToMostStarredGithubReposPresenterProtocol! { get set }
+ func getMostStarredGithubRepos(from page: Int, isToUsePullRefresh: Bool)
+}
+
+protocol InteractorToMostStarredGithubReposPresenterProtocol{
+ func mostStarredGithubReposSuccessFetch(repos: [GithubRepositoryEntity], isToUsePullRefresh: Bool, totalCount: Int)
+ func mostStarredGithubReposSuccessFailure()
+}
+
+protocol PresenterToMostStarredGithubReposRouterProtocol{
+ static func createModule()->UIViewController
+}
diff --git a/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposRouter.swift b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposRouter.swift
new file mode 100644
index 0000000..ceff9ec
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposRouter.swift
@@ -0,0 +1,32 @@
+//
+// MostStarredGithubReposRouter.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import UIKit
+
+class MostStarredGithubReposRouter: PresenterToMostStarredGithubReposRouterProtocol{
+
+ static func createModule() -> UIViewController {
+
+ let mostStarredGithubReposView = MostStarredGithubReposView()
+ let mostStarredGithubReposInteractor = MostStarredGithubReposInteractor()
+ let mostStarredGithubReposRouter = MostStarredGithubReposRouter()
+
+ let mostStarredGithubReposPresenter = MostStarredGithubReposPresenter(
+ view: mostStarredGithubReposView,
+ interactor: mostStarredGithubReposInteractor,
+ router: mostStarredGithubReposRouter
+ )
+
+ mostStarredGithubReposView.presenter = mostStarredGithubReposPresenter
+ mostStarredGithubReposInteractor.presenter = mostStarredGithubReposPresenter
+
+ return mostStarredGithubReposView
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposTableViewCell.swift b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposTableViewCell.swift
new file mode 100644
index 0000000..9a52969
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposTableViewCell.swift
@@ -0,0 +1,139 @@
+//
+// MostStarredGithubReposTableViewCell.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import UIKit
+import Kingfisher
+
+class MostStarredGithubReposTableViewCell: UITableViewCell {
+
+ private let repositoryNameLabel: UILabel = {
+ let label = UILabel()
+ label.translatesAutoresizingMaskIntoConstraints = false
+ label.font = .boldSystemFont(ofSize: 17)
+ label.numberOfLines = 2
+ return label
+ }()
+
+ private let repositoryDescriptionLabel: UILabel = {
+ let label = UILabel()
+ label.translatesAutoresizingMaskIntoConstraints = false
+ label.font = .systemFont(ofSize: 13)
+ label.numberOfLines = 3
+ return label
+ }()
+
+ private let repositoryOwnerImageView: UIImageView = {
+ let imageView = UIImageView()
+ imageView.translatesAutoresizingMaskIntoConstraints = false
+ imageView.image = #imageLiteral(resourceName: "empty-avatar-icon")
+ return imageView
+ }()
+
+ private let repositoryOwnerNameLabel: UILabel = {
+ let label = UILabel()
+ label.translatesAutoresizingMaskIntoConstraints = false
+ label.font = .systemFont(ofSize: 13)
+ return label
+ }()
+
+ private let repositoryStarImageView: UIImageView = {
+ let imageView = UIImageView()
+ imageView.translatesAutoresizingMaskIntoConstraints = false
+ imageView.image = #imageLiteral(resourceName: "star_icon")
+ return imageView
+ }()
+
+ private let repositoryNumberOfStarsLabel: UILabel = {
+ let label = UILabel()
+ label.translatesAutoresizingMaskIntoConstraints = false
+ label.font = .systemFont(ofSize: 13)
+ return label
+ }()
+
+ private let topBottomSpacing : CGFloat = 20
+ private let leadingTrailingSpacing: CGFloat = 30
+
+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
+ super.init(style: style, reuseIdentifier: reuseIdentifier)
+ self.createCellViewAutoLayout()
+ }
+
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+ self.createCellViewAutoLayout()
+ }
+
+ func fillView(repositoryName: String, repositoryDescription: String, repositoryOwnerImageLink: URL?, repositoryOwnerName: String, repositoryNumberOfStars: String) {
+
+ self.repositoryNameLabel.text = repositoryName
+ self.repositoryDescriptionLabel.text = repositoryDescription
+ self.repositoryOwnerNameLabel.text = repositoryOwnerName
+ self.repositoryNumberOfStarsLabel.text = repositoryNumberOfStars
+
+ if let _ = repositoryOwnerImageLink{
+ self.repositoryOwnerImageView.kf.setImage(with: repositoryOwnerImageLink!)
+ }
+
+ }
+
+ override func prepareForReuse() {
+ super.prepareForReuse()
+
+ self.repositoryOwnerImageView.image = #imageLiteral(resourceName: "empty-avatar-icon")
+
+ }
+
+}
+
+extension MostStarredGithubReposTableViewCell{
+
+ private func createCellViewAutoLayout(){
+
+ self.contentView.addSubview(self.repositoryNameLabel)
+ self.contentView.addSubview(self.repositoryDescriptionLabel)
+ self.contentView.addSubview(self.repositoryOwnerImageView)
+ self.contentView.addSubview(self.repositoryOwnerNameLabel)
+ self.contentView.addSubview(self.repositoryStarImageView)
+ self.contentView.addSubview(self.repositoryNumberOfStarsLabel)
+
+ NSLayoutConstraint.activate([
+
+ self.repositoryNameLabel.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: self.topBottomSpacing),
+ self.repositoryNameLabel.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: self.leadingTrailingSpacing),
+ self.repositoryNameLabel.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -self.leadingTrailingSpacing),
+
+ self.repositoryDescriptionLabel.topAnchor.constraint(equalTo: self.repositoryNameLabel.bottomAnchor, constant: 10),
+ self.repositoryDescriptionLabel.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: self.leadingTrailingSpacing),
+ self.repositoryDescriptionLabel.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -self.leadingTrailingSpacing),
+
+ self.repositoryOwnerImageView.topAnchor.constraint(equalTo: self.repositoryDescriptionLabel.bottomAnchor, constant: 10),
+ self.repositoryOwnerImageView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -self.topBottomSpacing),
+ self.repositoryOwnerImageView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: self.leadingTrailingSpacing),
+ self.repositoryOwnerImageView.widthAnchor.constraint(equalToConstant: 20.0),
+ self.repositoryOwnerImageView.heightAnchor.constraint(equalTo: self.repositoryOwnerImageView.widthAnchor),
+
+ self.repositoryOwnerNameLabel.leadingAnchor.constraint(equalTo: self.repositoryOwnerImageView.trailingAnchor, constant: 6),
+ self.repositoryOwnerNameLabel.centerYAnchor.constraint(equalTo: self.repositoryOwnerImageView.centerYAnchor),
+
+ self.repositoryStarImageView.leadingAnchor.constraint(equalTo: self.repositoryOwnerNameLabel.trailingAnchor, constant: 15),
+ self.repositoryStarImageView.centerYAnchor.constraint(equalTo: self.repositoryOwnerImageView.centerYAnchor),
+ self.repositoryStarImageView.widthAnchor.constraint(equalToConstant: 15.0),
+ self.repositoryStarImageView.heightAnchor.constraint(equalTo: self.repositoryStarImageView.widthAnchor),
+
+ self.repositoryNumberOfStarsLabel.leadingAnchor.constraint(equalTo: self.repositoryStarImageView.trailingAnchor, constant: 6),
+ self.repositoryNumberOfStarsLabel.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -self.leadingTrailingSpacing),
+ self.repositoryNumberOfStarsLabel.centerYAnchor.constraint(equalTo: self.repositoryOwnerImageView.centerYAnchor),
+
+ ])
+
+ self.repositoryNameLabel.setContentHuggingPriority(.fittingSizeLevel, for: .vertical)
+ self.repositoryOwnerNameLabel.setContentHuggingPriority(.fittingSizeLevel, for: .horizontal)
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposUI.swift b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposUI.swift
new file mode 100644
index 0000000..8c78af0
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposUI.swift
@@ -0,0 +1,60 @@
+//
+// MostStarredGithubReposUI.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import UIKit
+
+class MostStarredGithubReposUI: UIViewController{
+
+ let mostStarredReposTableView: UITableView = {
+ let tableView = UITableView()
+ tableView.translatesAutoresizingMaskIntoConstraints = false
+ tableView.backgroundColor = .white
+ tableView.separatorInset = .zero
+ tableView.tableFooterView = UIView()
+ return tableView
+ }()
+
+ let loadingIndicatorView: UIActivityIndicatorView = {
+ let indicator = UIActivityIndicatorView()
+ indicator.translatesAutoresizingMaskIntoConstraints = false
+ indicator.color = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
+ indicator.hidesWhenStopped = true
+ return indicator
+ }()
+
+ let refreshControl: UIRefreshControl = {
+ let refreshControl = UIRefreshControl()
+ refreshControl.tintColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
+ refreshControl.attributedTitle = NSAttributedString(string: "pull_to_refresh".localized)
+ return refreshControl
+ }()
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ self.view.addSubview(self.mostStarredReposTableView)
+ self.view.addSubview(self.loadingIndicatorView)
+ self.mostStarredReposTableView.refreshControl = self.refreshControl
+
+ NSLayoutConstraint.activate([
+
+ self.mostStarredReposTableView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
+ self.mostStarredReposTableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
+ self.mostStarredReposTableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
+ self.mostStarredReposTableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
+
+ self.loadingIndicatorView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
+ self.loadingIndicatorView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
+
+ ])
+
+ self.navigationController?.navigationBar.topItem?.title = "mostStarredGithubRepos.trending_repos".localized
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposView.swift b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposView.swift
new file mode 100644
index 0000000..278c181
--- /dev/null
+++ b/mobile-coding-challenge/Controllers/Most Starred Github Repos/MostStarredGithubReposView.swift
@@ -0,0 +1,126 @@
+//
+// MostStarredGithubReposView.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import UIKit
+
+class MostStarredGithubReposView: MostStarredGithubReposUI, PresenterToMostStarredGithubReposViewProtocol{
+
+ var presenter: ViewToMostStarredGithubReposPresenterProtocol!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ self.mostStarredReposTableView.dataSource = self
+ self.mostStarredReposTableView.delegate = self
+ self.mostStarredReposTableView.register(MostStarredGithubReposTableViewCell.self, forCellReuseIdentifier: "\(MostStarredGithubReposTableViewCell.self)")
+
+ self.refreshControl.addTarget(self, action: #selector(self.refreshMostStarredGithubReposData), for: .valueChanged)
+
+ self.presenter.viewDidLoad()
+
+ }
+
+ func reloadData() {
+ self.mostStarredReposTableView.reloadData()
+ }
+
+ func showLoader() {
+ self.mostStarredReposTableView.isUserInteractionEnabled = false
+ self.mostStarredReposTableView.separatorStyle = .none
+ self.loadingIndicatorView.startAnimating()
+ }
+
+ func hideLoader() {
+ self.mostStarredReposTableView.isUserInteractionEnabled = true
+ self.mostStarredReposTableView.separatorStyle = .singleLine
+ self.loadingIndicatorView.stopAnimating()
+ self.refreshControl.endRefreshing()
+ self.mostStarredReposTableView.tableFooterView = nil
+ }
+
+ func showResponseError(){
+ self.loadingIndicatorView.stopAnimating()
+ self.refreshControl.endRefreshing()
+ self.mostStarredReposTableView.tableFooterView = nil
+ self.showSimpleAlert(title: "errors.something_went_wrong".localized, message: "mostStarredGithubRepos.errors.while_fetching_for_repos_description".localized)
+ }
+
+ @objc
+ func refreshMostStarredGithubReposData(){
+ self.presenter.interactor.getMostStarredGithubRepos(from: 1, isToUsePullRefresh: true)
+ }
+
+}
+
+extension MostStarredGithubReposView: UITableViewDataSource, UITableViewDelegate{
+
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return self.presenter.mostStarredGithubRepos.count
+ }
+
+ func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
+
+ if indexPath.row == self.presenter.mostStarredGithubRepos.count - 1 {
+
+ let totalNumberOfMostStarredGithubRepos = self.presenter.totalNumberOfMostStarredGithubRepos
+
+ if totalNumberOfMostStarredGithubRepos != -1 && totalNumberOfMostStarredGithubRepos ?? -1 > self.presenter.mostStarredGithubRepos.count{
+
+ let _view = UIView(
+ frame: .init(
+ x: 0,
+ y: 0,
+ width: tableView.contentSize.width,
+ height: 40
+ )
+ )
+
+ let indicatorView = UIActivityIndicatorView(frame: .init(
+ x: _view.frame.width / 2,
+ y: _view.frame.height / 2,
+ width: 20,
+ height: 20
+ )
+ )
+
+ indicatorView.startAnimating()
+ _view.addSubview(indicatorView)
+
+ self.mostStarredReposTableView.tableFooterView = _view
+
+ self.presenter.interactor.getMostStarredGithubRepos(from: self.presenter.activePage, isToUsePullRefresh: false)
+
+ }
+
+ }
+
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+
+ let mostStarredGithubReposCell = tableView.dequeueReusableCell(withIdentifier: "\(MostStarredGithubReposTableViewCell.self)", for: indexPath) as! MostStarredGithubReposTableViewCell
+
+ let mostStarredGithubRepo = self.presenter.mostStarredGithubRepos[indexPath.row]
+
+ mostStarredGithubReposCell.fillView(
+ repositoryName: mostStarredGithubRepo.getName(),
+ repositoryDescription: mostStarredGithubRepo.getDescription(),
+ repositoryOwnerImageLink: mostStarredGithubRepo.getOwnerImageURL(),
+ repositoryOwnerName: mostStarredGithubRepo.getOwnerName(),
+ repositoryNumberOfStars: mostStarredGithubRepo.getShortNumberOfStars()
+ )
+
+ return mostStarredGithubReposCell
+
+ }
+
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ tableView.deselectRow(at: indexPath, animated: true)
+ }
+
+}
diff --git a/mobile-coding-challenge/Extensions/Date + Extension.swift b/mobile-coding-challenge/Extensions/Date + Extension.swift
new file mode 100644
index 0000000..38cfae1
--- /dev/null
+++ b/mobile-coding-challenge/Extensions/Date + Extension.swift
@@ -0,0 +1,23 @@
+//
+// File.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import Foundation
+
+extension Date{
+
+ func formattedDate(using dateFormat: String)->String{
+
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateFormat = dateFormat
+ let formattedStringDate = dateFormatter.string(from: self)
+
+ return formattedStringDate
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Extensions/Int + Extension.swift b/mobile-coding-challenge/Extensions/Int + Extension.swift
new file mode 100644
index 0000000..7073ccd
--- /dev/null
+++ b/mobile-coding-challenge/Extensions/Int + Extension.swift
@@ -0,0 +1,34 @@
+//
+// Int + Extension.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import Foundation
+
+extension Int{
+
+ var shortValue: String{
+
+ let num: Double = Double(abs(self))
+
+ if (num < 1000.0){
+ return "\(self)"
+ }
+
+ let sign : String = (self < 0) ? "-" : ""
+ let exp : Int = Int(log10(num) / 3.0 )
+ let units : [String] = ["K","M"]
+ let roundedNum: Double = round(10 * num / pow(1000.0, Double(exp))) / 10
+
+ if exp <= units.count{
+ return "\(sign)\(roundedNum)\(units[exp-1])"
+ }
+
+ return "+\(Int(roundedNum))..."
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Extensions/String + Extension.swift b/mobile-coding-challenge/Extensions/String + Extension.swift
new file mode 100644
index 0000000..046b4f6
--- /dev/null
+++ b/mobile-coding-challenge/Extensions/String + Extension.swift
@@ -0,0 +1,17 @@
+//
+// String + Extension.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import Foundation
+
+extension String{
+
+ var localized: String{
+ return NSLocalizedString(self, comment: "")
+ }
+
+}
diff --git a/mobile-coding-challenge/Extensions/UIViewController + Extension.swift b/mobile-coding-challenge/Extensions/UIViewController + Extension.swift
new file mode 100644
index 0000000..c9c089c
--- /dev/null
+++ b/mobile-coding-challenge/Extensions/UIViewController + Extension.swift
@@ -0,0 +1,25 @@
+//
+// UIViewController + Extension.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import UIKit
+
+extension UIViewController{
+
+ func showSimpleAlert(title: String, message: String){
+
+ let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ let okAlertAction = UIAlertAction(title: "ok".localized, style: .default)
+
+ alert.addAction(okAlertAction)
+
+ self.present(alert, animated: true)
+
+ }
+
+}
diff --git a/mobile-coding-challenge/Helpers/RequestHandler.swift b/mobile-coding-challenge/Helpers/RequestHandler.swift
new file mode 100644
index 0000000..8dc2a70
--- /dev/null
+++ b/mobile-coding-challenge/Helpers/RequestHandler.swift
@@ -0,0 +1,60 @@
+//
+// RequestHandler.swift
+// mobile-coding-challenge
+//
+// Created by Mobile on 9/19/20.
+// Copyright © 2020 Zakariae. All rights reserved.
+//
+
+import Foundation
+import Moya
+
+enum RequestHandler{
+ case getMostGithubRepos(created_at: String, page: Int)
+}
+
+extension RequestHandler: TargetType{
+
+ var baseURL: URL {
+ return URL(string: "https://api.github.com/search/repositories")!
+ }
+
+ var path: String {
+ switch self{
+ case .getMostGithubRepos(_, _):
+ return ""
+ }
+ }
+
+ var method: Moya.Method {
+ switch self{
+ case .getMostGithubRepos:
+ return .get
+ }
+ }
+
+ var sampleData: Data { return .init() }
+
+ var task: Task {
+ switch self{
+ case .getMostGithubRepos(let created_at, let page):
+ return .requestParameters(
+ parameters: [
+ "q" : "created:>\(created_at)",
+ "page" : page,
+ "sort" : "stars",
+ "order": "desc"
+ ],
+ encoding: URLEncoding.queryString
+ )
+ }
+ }
+
+ var headers: [String : String]? {
+ switch self{
+ case .getMostGithubRepos(_, _):
+ return ["Content-type": "application/json"]
+ }
+ }
+
+}
diff --git a/mobile-coding-challenge/Info.plist b/mobile-coding-challenge/Info.plist
new file mode 100644
index 0000000..fac5cdf
--- /dev/null
+++ b/mobile-coding-challenge/Info.plist
@@ -0,0 +1,45 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UIStatusBarStyle
+ UIStatusBarStyleDarkContent
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/mobile-coding-challenge/Localizable Files/Localizable.strings b/mobile-coding-challenge/Localizable Files/Localizable.strings
new file mode 100644
index 0000000..ac56c93
--- /dev/null
+++ b/mobile-coding-challenge/Localizable Files/Localizable.strings
@@ -0,0 +1,21 @@
+/*
+ Localizable.strings
+ mobile-coding-challenge
+
+ Created by Mobile on 9/19/20.
+ Copyright © 2020 Zakariae. All rights reserved.
+*/
+
+//MARK: GENERAL
+
+"pull_to_refresh" = "Pull to refresh";
+
+"errors.something_went_wrong" = "Something went wrong";
+
+"ok" = "OK";
+
+//MARK: MOST STARRED GITHUB REPOS VIEW
+
+"mostStarredGithubRepos.trending_repos" = "Trending Repos";
+
+"mostStarredGithubRepos.errors.while_fetching_for_repos_description" = "Error while searching for the most starred github repos.\nPull to refresh or try again later";
diff --git a/mockup.png b/mockup.png
deleted file mode 100644
index 9cfb608..0000000
Binary files a/mockup.png and /dev/null differ
diff --git a/row-explained.png b/row-explained.png
deleted file mode 100644
index ab4d2b8..0000000
Binary files a/row-explained.png and /dev/null differ