diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..273ec9d --- /dev/null +++ b/.gitignore @@ -0,0 +1,69 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +PlikiTestowe +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ab86784 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj @@ -0,0 +1,580 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 9246EC862090EDC200F7A40F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9246EC852090EDC200F7A40F /* AppDelegate.swift */; }; + 9246EC882090EDC200F7A40F /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9246EC872090EDC200F7A40F /* ViewController.swift */; }; + 9246EC8B2090EDC200F7A40F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9246EC892090EDC200F7A40F /* Main.storyboard */; }; + 9246EC8D2090EDC200F7A40F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9246EC8C2090EDC200F7A40F /* Assets.xcassets */; }; + 9246EC902090EDC200F7A40F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9246EC8E2090EDC200F7A40F /* LaunchScreen.storyboard */; }; + 9246EC9B2090EDC300F7A40F /* MobileInternshipTaskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9246EC9A2090EDC300F7A40F /* MobileInternshipTaskTests.swift */; }; + 9266F43C2098E891005F6A24 /* ConnectedToNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9266F43B2098E891005F6A24 /* ConnectedToNetwork.swift */; }; + 9266F43D2098E891005F6A24 /* ConnectedToNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9266F43B2098E891005F6A24 /* ConnectedToNetwork.swift */; }; + 9266F440209B1D1F005F6A24 /* MakeRoundedCornersUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9266F43F209B1D1F005F6A24 /* MakeRoundedCornersUIView.swift */; }; + 9266F441209B5CA3005F6A24 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9246EC872090EDC200F7A40F /* ViewController.swift */; }; + 9266F442209B5CA8005F6A24 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9246EC852090EDC200F7A40F /* AppDelegate.swift */; }; + 9266F443209B5CAB005F6A24 /* Owner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9298226320970B0800837D92 /* Owner.swift */; }; + 9266F444209B5CAF005F6A24 /* UserRepos.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92DD94B72091371C008FD290 /* UserRepos.swift */; }; + 9266F445209B5CCE005F6A24 /* MakeRoundedCornersUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9266F43F209B1D1F005F6A24 /* MakeRoundedCornersUIView.swift */; }; + 9266F446209B5CE6005F6A24 /* ReposCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 929822662097127200837D92 /* ReposCell.swift */; }; + 9298226420970B0800837D92 /* Owner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9298226320970B0800837D92 /* Owner.swift */; }; + 929822682097127200837D92 /* ReposCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 929822662097127200837D92 /* ReposCell.swift */; }; + 929822692097127200837D92 /* ReposCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 929822672097127200837D92 /* ReposCell.xib */; }; + 9298226B20979C7800837D92 /* DetailRepoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9298226A20979C7800837D92 /* DetailRepoViewController.swift */; }; + 9298226C20979C7800837D92 /* DetailRepoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9298226A20979C7800837D92 /* DetailRepoViewController.swift */; }; + 92A41D3820D0028E00F1F2A1 /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92A41D3720D0028E00F1F2A1 /* Alert.swift */; }; + 92A41D3A20D006CE00F1F2A1 /* TopViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92A41D3920D006CE00F1F2A1 /* TopViewController.swift */; }; + 92DD94B82091371C008FD290 /* UserRepos.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92DD94B72091371C008FD290 /* UserRepos.swift */; }; + 92DD94BC2092507F008FD290 /* ReposTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */; }; + 92DD94BD2092507F008FD290 /* ReposTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */; }; + 92E0FB5D20C6C0A0005D1F79 /* ReposFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92E0FB5C20C6C0A0005D1F79 /* ReposFetcher.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 9246EC972090EDC300F7A40F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9246EC7A2090EDC200F7A40F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9246EC812090EDC200F7A40F; + remoteInfo = MobileInternshipTask; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 9246EC822090EDC200F7A40F /* MobileInternshipTask.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MobileInternshipTask.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9246EC852090EDC200F7A40F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 9246EC872090EDC200F7A40F /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 9246EC8A2090EDC200F7A40F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 9246EC8C2090EDC200F7A40F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 9246EC8F2090EDC200F7A40F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 9246EC912090EDC200F7A40F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9246EC962090EDC300F7A40F /* MobileInternshipTaskTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MobileInternshipTaskTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 9246EC9A2090EDC300F7A40F /* MobileInternshipTaskTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileInternshipTaskTests.swift; sourceTree = ""; }; + 9246EC9C2090EDC300F7A40F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9266F43B2098E891005F6A24 /* ConnectedToNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectedToNetwork.swift; sourceTree = ""; }; + 9266F43F209B1D1F005F6A24 /* MakeRoundedCornersUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MakeRoundedCornersUIView.swift; sourceTree = ""; }; + 9298226320970B0800837D92 /* Owner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Owner.swift; sourceTree = ""; }; + 929822662097127200837D92 /* ReposCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReposCell.swift; sourceTree = ""; }; + 929822672097127200837D92 /* ReposCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ReposCell.xib; sourceTree = ""; }; + 9298226A20979C7800837D92 /* DetailRepoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailRepoViewController.swift; sourceTree = ""; }; + 92A41D3720D0028E00F1F2A1 /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = ""; }; + 92A41D3920D006CE00F1F2A1 /* TopViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopViewController.swift; sourceTree = ""; }; + 92DD94B72091371C008FD290 /* UserRepos.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRepos.swift; sourceTree = ""; }; + 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReposTableViewController.swift; sourceTree = ""; }; + 92E0FB5C20C6C0A0005D1F79 /* ReposFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReposFetcher.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 9246EC7F2090EDC200F7A40F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9246EC932090EDC300F7A40F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9246EC792090EDC200F7A40F = { + isa = PBXGroup; + children = ( + 9246EC842090EDC200F7A40F /* MobileInternshipTask */, + 9246EC992090EDC300F7A40F /* MobileInternshipTaskTests */, + 9246EC832090EDC200F7A40F /* Products */, + ); + sourceTree = ""; + }; + 9246EC832090EDC200F7A40F /* Products */ = { + isa = PBXGroup; + children = ( + 9246EC822090EDC200F7A40F /* MobileInternshipTask.app */, + 9246EC962090EDC300F7A40F /* MobileInternshipTaskTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 9246EC842090EDC200F7A40F /* MobileInternshipTask */ = { + isa = PBXGroup; + children = ( + 92DD94B62091243C008FD290 /* Model */, + 92DD94B5209116BE008FD290 /* Controller */, + 92DD94B42091168C008FD290 /* View */, + 9266F43E209B1CFA005F6A24 /* Extensions */, + 9246EC912090EDC200F7A40F /* Info.plist */, + ); + path = MobileInternshipTask; + sourceTree = ""; + }; + 9246EC992090EDC300F7A40F /* MobileInternshipTaskTests */ = { + isa = PBXGroup; + children = ( + 9246EC9A2090EDC300F7A40F /* MobileInternshipTaskTests.swift */, + 9246EC9C2090EDC300F7A40F /* Info.plist */, + ); + path = MobileInternshipTaskTests; + sourceTree = ""; + }; + 9266F43E209B1CFA005F6A24 /* Extensions */ = { + isa = PBXGroup; + children = ( + 9266F43F209B1D1F005F6A24 /* MakeRoundedCornersUIView.swift */, + 92A41D3920D006CE00F1F2A1 /* TopViewController.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + 929822652097119C00837D92 /* ReposCell */ = { + isa = PBXGroup; + children = ( + 929822662097127200837D92 /* ReposCell.swift */, + 929822672097127200837D92 /* ReposCell.xib */, + ); + path = ReposCell; + sourceTree = ""; + }; + 92DD94B42091168C008FD290 /* View */ = { + isa = PBXGroup; + children = ( + 929822652097119C00837D92 /* ReposCell */, + 9246EC892090EDC200F7A40F /* Main.storyboard */, + 9246EC8C2090EDC200F7A40F /* Assets.xcassets */, + 9246EC8E2090EDC200F7A40F /* LaunchScreen.storyboard */, + ); + path = View; + sourceTree = ""; + }; + 92DD94B5209116BE008FD290 /* Controller */ = { + isa = PBXGroup; + children = ( + 9246EC852090EDC200F7A40F /* AppDelegate.swift */, + 9246EC872090EDC200F7A40F /* ViewController.swift */, + 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */, + 9298226A20979C7800837D92 /* DetailRepoViewController.swift */, + 92A41D3720D0028E00F1F2A1 /* Alert.swift */, + 92E0FB5B20C06815005D1F79 /* Networking */, + ); + path = Controller; + sourceTree = ""; + }; + 92DD94B62091243C008FD290 /* Model */ = { + isa = PBXGroup; + children = ( + 92DD94B72091371C008FD290 /* UserRepos.swift */, + 9298226320970B0800837D92 /* Owner.swift */, + ); + path = Model; + sourceTree = ""; + }; + 92E0FB5B20C06815005D1F79 /* Networking */ = { + isa = PBXGroup; + children = ( + 92E0FB5C20C6C0A0005D1F79 /* ReposFetcher.swift */, + 9266F43B2098E891005F6A24 /* ConnectedToNetwork.swift */, + ); + path = Networking; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 9246EC812090EDC200F7A40F /* MobileInternshipTask */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9246EC9F2090EDC300F7A40F /* Build configuration list for PBXNativeTarget "MobileInternshipTask" */; + buildPhases = ( + 9246EC7E2090EDC200F7A40F /* Sources */, + 9246EC7F2090EDC200F7A40F /* Frameworks */, + 9246EC802090EDC200F7A40F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MobileInternshipTask; + productName = MobileInternshipTask; + productReference = 9246EC822090EDC200F7A40F /* MobileInternshipTask.app */; + productType = "com.apple.product-type.application"; + }; + 9246EC952090EDC300F7A40F /* MobileInternshipTaskTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9246ECA22090EDC300F7A40F /* Build configuration list for PBXNativeTarget "MobileInternshipTaskTests" */; + buildPhases = ( + 9246EC922090EDC300F7A40F /* Sources */, + 9246EC932090EDC300F7A40F /* Frameworks */, + 9246EC942090EDC300F7A40F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9246EC982090EDC300F7A40F /* PBXTargetDependency */, + ); + name = MobileInternshipTaskTests; + productName = MobileInternshipTaskTests; + productReference = 9246EC962090EDC300F7A40F /* MobileInternshipTaskTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 9246EC7A2090EDC200F7A40F /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0940; + LastUpgradeCheck = 0940; + ORGANIZATIONNAME = "Dawid Czmyr"; + TargetAttributes = { + 9246EC812090EDC200F7A40F = { + CreatedOnToolsVersion = 9.4; + }; + 9246EC952090EDC300F7A40F = { + CreatedOnToolsVersion = 9.4; + TestTargetID = 9246EC812090EDC200F7A40F; + }; + }; + }; + buildConfigurationList = 9246EC7D2090EDC200F7A40F /* Build configuration list for PBXProject "MobileInternshipTask" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 9246EC792090EDC200F7A40F; + productRefGroup = 9246EC832090EDC200F7A40F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 9246EC812090EDC200F7A40F /* MobileInternshipTask */, + 9246EC952090EDC300F7A40F /* MobileInternshipTaskTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 9246EC802090EDC200F7A40F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9246EC902090EDC200F7A40F /* LaunchScreen.storyboard in Resources */, + 9246EC8D2090EDC200F7A40F /* Assets.xcassets in Resources */, + 9246EC8B2090EDC200F7A40F /* Main.storyboard in Resources */, + 929822692097127200837D92 /* ReposCell.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9246EC942090EDC300F7A40F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 9246EC7E2090EDC200F7A40F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 92A41D3A20D006CE00F1F2A1 /* TopViewController.swift in Sources */, + 9246EC882090EDC200F7A40F /* ViewController.swift in Sources */, + 9246EC862090EDC200F7A40F /* AppDelegate.swift in Sources */, + 92DD94B82091371C008FD290 /* UserRepos.swift in Sources */, + 9266F43C2098E891005F6A24 /* ConnectedToNetwork.swift in Sources */, + 9298226B20979C7800837D92 /* DetailRepoViewController.swift in Sources */, + 92E0FB5D20C6C0A0005D1F79 /* ReposFetcher.swift in Sources */, + 9298226420970B0800837D92 /* Owner.swift in Sources */, + 9266F440209B1D1F005F6A24 /* MakeRoundedCornersUIView.swift in Sources */, + 92DD94BC2092507F008FD290 /* ReposTableViewController.swift in Sources */, + 92A41D3820D0028E00F1F2A1 /* Alert.swift in Sources */, + 929822682097127200837D92 /* ReposCell.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9246EC922090EDC300F7A40F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9266F442209B5CA8005F6A24 /* AppDelegate.swift in Sources */, + 9266F441209B5CA3005F6A24 /* ViewController.swift in Sources */, + 9266F444209B5CAF005F6A24 /* UserRepos.swift in Sources */, + 9266F443209B5CAB005F6A24 /* Owner.swift in Sources */, + 9246EC9B2090EDC300F7A40F /* MobileInternshipTaskTests.swift in Sources */, + 9298226C20979C7800837D92 /* DetailRepoViewController.swift in Sources */, + 9266F445209B5CCE005F6A24 /* MakeRoundedCornersUIView.swift in Sources */, + 92DD94BD2092507F008FD290 /* ReposTableViewController.swift in Sources */, + 9266F43D2098E891005F6A24 /* ConnectedToNetwork.swift in Sources */, + 9266F446209B5CE6005F6A24 /* ReposCell.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 9246EC982090EDC300F7A40F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9246EC812090EDC200F7A40F /* MobileInternshipTask */; + targetProxy = 9246EC972090EDC300F7A40F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 9246EC892090EDC200F7A40F /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 9246EC8A2090EDC200F7A40F /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 9246EC8E2090EDC200F7A40F /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 9246EC8F2090EDC200F7A40F /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 9246EC9D2090EDC300F7A40F /* 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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + 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 = 11.4; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 9246EC9E2090EDC300F7A40F /* 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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + 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 = 11.4; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 9246ECA02090EDC300F7A40F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = NCQ33B9RSH; + INFOPLIST_FILE = MobileInternshipTask/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = dawid.czmyr.MobileInternshipTask; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 9246ECA12090EDC300F7A40F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = NCQ33B9RSH; + INFOPLIST_FILE = MobileInternshipTask/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = dawid.czmyr.MobileInternshipTask; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 9246ECA32090EDC300F7A40F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = MobileInternshipTaskTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = dawid.czmyr.MobileInternshipTaskTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MobileInternshipTask.app/MobileInternshipTask"; + }; + name = Debug; + }; + 9246ECA42090EDC300F7A40F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = MobileInternshipTaskTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = dawid.czmyr.MobileInternshipTaskTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MobileInternshipTask.app/MobileInternshipTask"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 9246EC7D2090EDC200F7A40F /* Build configuration list for PBXProject "MobileInternshipTask" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9246EC9D2090EDC300F7A40F /* Debug */, + 9246EC9E2090EDC300F7A40F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9246EC9F2090EDC300F7A40F /* Build configuration list for PBXNativeTarget "MobileInternshipTask" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9246ECA02090EDC300F7A40F /* Debug */, + 9246ECA12090EDC300F7A40F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9246ECA22090EDC300F7A40F /* Build configuration list for PBXNativeTarget "MobileInternshipTaskTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9246ECA32090EDC300F7A40F /* Debug */, + 9246ECA42090EDC300F7A40F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 9246EC7A2090EDC200F7A40F /* Project object */; +} diff --git a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..516c66e --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/Alert.swift b/MobileInternshipTask/MobileInternshipTask/Controller/Alert.swift new file mode 100644 index 0000000..5a751b3 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/Alert.swift @@ -0,0 +1,18 @@ +// +// Alerts.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 12/06/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation +import UIKit + +class Alert { + static func showMessage(title: String, msg: String) { + let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil)) + UIApplication.topViewController()?.present(alert, animated: true, completion: nil) + } +} diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift b/MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift new file mode 100644 index 0000000..147e542 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 25/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + + } + + func applicationDidEnterBackground(_ application: UIApplication) { + + } + + func applicationWillEnterForeground(_ application: UIApplication) { + + } + + func applicationDidBecomeActive(_ application: UIApplication) { + + } + + func applicationWillTerminate(_ application: UIApplication) { + + } + +} + diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift new file mode 100644 index 0000000..f45467b --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift @@ -0,0 +1,82 @@ +// +// DetailRepoViewController.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 30/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import UIKit + +class DetailRepoViewController: UIViewController { + @IBOutlet weak var repoNameLabel: UILabel! + @IBOutlet weak var descriptionLabel: UILabel! + @IBOutlet weak var languageLabel: UILabel! + @IBOutlet weak var createdLabel: UILabel! + @IBOutlet weak var updatedLabel: UILabel! + @IBOutlet weak var watchersLabel: UILabel! + @IBOutlet weak var forksLabel: UILabel! + + var userRepo: UserRepos? + var createdDate: String? + var updatedDate: String? + + override func viewDidLoad() { + super.viewDidLoad() + convertDateToString() + roundedCorners() + setupLabels() + } + + func setupLabels() { + if let userRepos = userRepo { + repoNameLabel.text = userRepos.name + descriptionLabel.text = userRepos.description ?? "No description" + languageLabel.text = userRepos.language ?? "-" + watchersLabel.text = "Watchers: \((userRepos.watchers) ?? 0)" + forksLabel.text = "Forks: \(userRepos.forks ?? 0)" + updatedLabel.text = "Updated at: \n\(updatedDate ?? "-")" + createdLabel.text = "Created at: \n\(createdDate ?? "-")" + } + } + + @IBAction func seeDetailsButton(_ sender: Any) { + if let htmlUrl = userRepo?.html_url { + guard let url = URL(string: htmlUrl) else {return} + UIApplication.shared.open(url, options: [:], completionHandler: nil ) + } + } + + func roundedCorners() { + repoNameLabel.makeRoundedCorners() + descriptionLabel.makeRoundedCorners() + languageLabel.makeRoundedCorners() + createdLabel.makeRoundedCorners() + updatedLabel.makeRoundedCorners() + watchersLabel.makeRoundedCorners() + forksLabel.makeRoundedCorners() + } + + func convertDateToString() { + if let date = userRepo?.updated_at { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + if let dateFromString = dateFormatter.date(from: date) { + dateFormatter.dateStyle = .long + let dateToString = dateFormatter.string(from: dateFromString) + updatedDate = dateToString + } + } + + if let date = userRepo?.created_at { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + if let dateFromString = dateFormatter.date(from: date) { + dateFormatter.dateStyle = .long + let dateToString = dateFormatter.string(from: dateFromString) + createdDate = dateToString + } + } + } + +} diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/Networking/ConnectedToNetwork.swift b/MobileInternshipTask/MobileInternshipTask/Controller/Networking/ConnectedToNetwork.swift new file mode 100644 index 0000000..f9e7701 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/Networking/ConnectedToNetwork.swift @@ -0,0 +1,36 @@ +// +// ConnectedToNetwork.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 01/05/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation +import SystemConfiguration + +public class Reachability { + + class func isConnectedToNetwork() -> Bool { + var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) + zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress)) + zeroAddress.sin_family = sa_family_t(AF_INET) + + let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) { + $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in + SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress) + } + } + + var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0) + if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false { + return false + } + + let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0 + let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0 + let ret = (isReachable && !needsConnection) + + return ret + } +} diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/Networking/ReposFetcher.swift b/MobileInternshipTask/MobileInternshipTask/Controller/Networking/ReposFetcher.swift new file mode 100644 index 0000000..8ae5cf6 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/Networking/ReposFetcher.swift @@ -0,0 +1,30 @@ +// +// ReposFetcher.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 05/06/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation + +class ReposFetcher { + + private init() {} + static let shared = ReposFetcher() + + func reposFetcher(userName: String, completion: @escaping ([UserRepos]?, Error?) -> ()) { + let githubAPI = "https://api.github.com/users/" + userName + "/repos" + guard let url = URL(string: githubAPI) else { return } + URLSession.shared.dataTask(with: url) { (data, response, error) in + if let data = data { + do { + let repos = try JSONDecoder().decode([UserRepos].self, from: data) + completion(repos, nil) + } catch { + completion(nil, error) + } + } + }.resume() + } +} diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift new file mode 100644 index 0000000..10fa915 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift @@ -0,0 +1,88 @@ +// +// ReposTableViewController.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 26/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import UIKit + +class ReposTableViewController: UITableViewController { + + var repos: [UserRepos]? + var singleRepo: UserRepos? + let reposCell = "reposCell" + let detailRepo = "detailRepo" + + override func viewDidLoad() { + super.viewDidLoad() + userDoesntHaveRepos() + setUserPhotoInNav() + registerCell() + } + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == detailRepo { + guard let detailScreen = segue.destination as? DetailRepoViewController else { return } + detailScreen.userRepo = singleRepo + } + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + guard let repos = repos else { return 0 } + return repos.count + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell(withIdentifier: reposCell, for: indexPath) as? ReposCell else { return UITableViewCell() } + + if let repos = repos { + cell.repoTitleLabel.text = repos[indexPath.row].name + cell.languageLabel.text = repos[indexPath.row].language ?? "-" + } + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if let repos = repos { + let selectedRow = repos[indexPath.row] + singleRepo = selectedRow + performSegue(withIdentifier: detailRepo, sender: nil) + } + } + + func userDoesntHaveRepos() { + if repos?.isEmpty == true { + Alert.showMessage(title: "Oops looks like user exist but doesn't have any repos", msg: "Try again") + } + } + + func setUserPhotoInNav() { + if repos?.isEmpty == false { + if let repos = repos { + if let avatarUrl = repos[0].owner?.avatar_url { + guard let url = URL(string: avatarUrl) else { return } + URLSession.shared.dataTask(with: url) { (data, respone, error) in + if let error = error { + print(error) + } + if let dataImg = data { + let image = UIImage(data: dataImg) + DispatchQueue.main.async { + let imageView = UIImageView(image: image) + imageView.contentMode = .scaleAspectFit + self.navigationItem.titleView = imageView + } + } + }.resume() + } + } + } + } + + func registerCell() { + let customCellNibFile = UINib(nibName: "ReposCell", bundle: nil) + tableView.register(customCellNibFile, forCellReuseIdentifier: reposCell) + } + +} diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift new file mode 100644 index 0000000..ff795c4 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift @@ -0,0 +1,85 @@ +// +// ViewController.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 25/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + @IBOutlet weak var userNameTxtFiled: UITextField! + @IBOutlet weak var findUserOutlet: UIButton! + + let repoSegue = "repoSegue" + var reposArray: [UserRepos]? + var activityIndicator:UIActivityIndicatorView = UIActivityIndicatorView() + + override func viewDidLoad() { + super.viewDidLoad() + userNameTxtFiled.delegate = self + checkConnectionToNetwork() + addNavBarImage() + } + + override func viewWillAppear(_ animated: Bool) { + reposArray = nil + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any? ) { + if segue.identifier == repoSegue { + let reposTableViewController = segue.destination as! ReposTableViewController + reposTableViewController.repos = reposArray + } + } + + @IBAction func findUserButton(_ sender: Any) { + if let text = self.userNameTxtFiled.text { + ReposFetcher.shared.reposFetcher(userName: text) { (userRepos, error) in + if error != nil { + DispatchQueue.main.async { + Alert.showMessage(title: "User not Found", msg: "Try again") + } + } + DispatchQueue.main.async { + self.reposArray = userRepos + if self.reposArray != nil { + self.performSegue(withIdentifier: self.repoSegue, sender: ViewController.self) + } + } + } + } + userNameTxtFiled.text = "" + } + + func addNavBarImage() { + let image = #imageLiteral(resourceName: "logo_turkus") + let imageView = UIImageView(image: image) + imageView.contentMode = .scaleAspectFit + navigationItem.titleView = imageView + } + + func checkConnectionToNetwork() { + if Reachability.isConnectedToNetwork() == false { + Alert.showMessage(title: "No Internet connection", msg: "Try again") + } + } + +} + +extension ViewController: UITextFieldDelegate { + + func textField(_ userNameTxtFiled: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + let allowedCharacters = CharacterSet.urlUserAllowed + let characterSet = CharacterSet(charactersIn: string) + + if string == " " { + return false + } else { + return allowedCharacters.isSuperset(of: characterSet) + } + } + +} + diff --git a/MobileInternshipTask/MobileInternshipTask/Extensions/MakeRoundedCornersUIView.swift b/MobileInternshipTask/MobileInternshipTask/Extensions/MakeRoundedCornersUIView.swift new file mode 100644 index 0000000..41d5161 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Extensions/MakeRoundedCornersUIView.swift @@ -0,0 +1,17 @@ +// +// MakeRoundedCornersUIView.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 03/05/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation +import UIKit + +extension UIView { + func makeRoundedCorners() { + layer.cornerRadius = 10 + clipsToBounds = true + } +} diff --git a/MobileInternshipTask/MobileInternshipTask/Extensions/TopViewController.swift b/MobileInternshipTask/MobileInternshipTask/Extensions/TopViewController.swift new file mode 100644 index 0000000..13f09b2 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Extensions/TopViewController.swift @@ -0,0 +1,27 @@ +// +// TopViewController.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 12/06/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation +import UIKit + +extension UIApplication { + + static func topViewController(base: UIViewController? = UIApplication.shared.delegate?.window??.rootViewController) -> UIViewController? { + if let nav = base as? UINavigationController { + return topViewController(base: nav.visibleViewController) + } + if let tab = base as? UITabBarController, let selected = tab.selectedViewController { + return topViewController(base: selected) + } + if let presented = base?.presentedViewController { + return topViewController(base: presented) + } + + return base + } +} diff --git a/MobileInternshipTask/MobileInternshipTask/Info.plist b/MobileInternshipTask/MobileInternshipTask/Info.plist new file mode 100644 index 0000000..716d1ca --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIRequiresFullScreen + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift b/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift new file mode 100644 index 0000000..031e8c4 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift @@ -0,0 +1,13 @@ +// +// Owner.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 30/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation + +struct Owner: Codable { + let avatar_url: String? +} diff --git a/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift b/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift new file mode 100644 index 0000000..0be716a --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift @@ -0,0 +1,21 @@ +// +// UserRepos.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 26/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation + +struct UserRepos: Codable { + let name: String? + let owner: Owner? + let html_url: String? + let description: String? + let created_at: String? + let updated_at: String? + let language: String? + let forks: Int? + let watchers: Int? +} diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/AppIcon.appiconset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/Contents.json new file mode 100644 index 0000000..790c09f --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "background.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/background.png b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/background.png new file mode 100644 index 0000000..f43a5ef Binary files /dev/null and b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/background.png differ diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/button01.imageset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/button01.imageset/Contents.json new file mode 100644 index 0000000..e4deef1 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/button01.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "button01.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/button01.imageset/button01.png b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/button01.imageset/button01.png new file mode 100644 index 0000000..d136c57 Binary files /dev/null and b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/button01.imageset/button01.png differ diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_github_white.imageset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_github_white.imageset/Contents.json new file mode 100644 index 0000000..62fa27d --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_github_white.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logo_github_white.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_github_white.imageset/logo_github_white.png b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_github_white.imageset/logo_github_white.png new file mode 100644 index 0000000..f86cb13 Binary files /dev/null and b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_github_white.imageset/logo_github_white.png differ diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_turkus.imageset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_turkus.imageset/Contents.json new file mode 100644 index 0000000..346d476 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_turkus.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logo_turkus.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_turkus.imageset/logo_turkus.png b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_turkus.imageset/logo_turkus.png new file mode 100644 index 0000000..1f6ee7c Binary files /dev/null and b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_turkus.imageset/logo_turkus.png differ diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/see_full_details_button.imageset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/see_full_details_button.imageset/Contents.json new file mode 100644 index 0000000..80c3e47 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/see_full_details_button.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "see_full_details_button.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/see_full_details_button.imageset/see_full_details_button.png b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/see_full_details_button.imageset/see_full_details_button.png new file mode 100644 index 0000000..ba1b33b Binary files /dev/null and b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/see_full_details_button.imageset/see_full_details_button.png differ diff --git a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/LaunchScreen.storyboard b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f83f6fd --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard new file mode 100644 index 0000000..e16303e --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.swift b/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.swift new file mode 100644 index 0000000..d826418 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.swift @@ -0,0 +1,19 @@ +// +// ReposCell.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 30/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import UIKit + +class ReposCell: UITableViewCell { + @IBOutlet weak var repoTitleLabel: UILabel! + @IBOutlet weak var languageLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + } + +} diff --git a/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib b/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib new file mode 100644 index 0000000..2414569 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileInternshipTask/MobileInternshipTaskTests/Info.plist b/MobileInternshipTask/MobileInternshipTaskTests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTaskTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/MobileInternshipTask/MobileInternshipTaskTests/MobileInternshipTaskTests.swift b/MobileInternshipTask/MobileInternshipTaskTests/MobileInternshipTaskTests.swift new file mode 100644 index 0000000..93b1c3c --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTaskTests/MobileInternshipTaskTests.swift @@ -0,0 +1,21 @@ +// +// MobileInternshipTaskTests.swift +// MobileInternshipTaskTests +// +// Created by Dawid Ramone on 25/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import XCTest +@testable import MobileInternshipTask + +class MobileInternshipTaskTests: XCTestCase { + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + +}