From 7d680a2ff15db752fad0415fa185b02f28b4d24b Mon Sep 17 00:00:00 2001 From: dawidramone Date: Wed, 25 Apr 2018 19:13:56 +0200 Subject: [PATCH 01/15] first commit --- .gitignore | 69 +++ .../project.pbxproj | 466 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../MobileInternshipTask/AppDelegate.swift | 46 ++ .../AppIcon.appiconset/Contents.json | 98 ++++ .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../Base.lproj/Main.storyboard | 24 + .../MobileInternshipTask/Info.plist | 45 ++ .../MobileInternshipTask/ViewController.swift | 25 + .../MobileInternshipTaskTests/Info.plist | 22 + .../MobileInternshipTaskTests.swift | 36 ++ 13 files changed, 877 insertions(+) create mode 100644 .gitignore create mode 100644 MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj create mode 100644 MobileInternshipTask/MobileInternshipTask.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 MobileInternshipTask/MobileInternshipTask.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 MobileInternshipTask/MobileInternshipTask/AppDelegate.swift create mode 100644 MobileInternshipTask/MobileInternshipTask/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 MobileInternshipTask/MobileInternshipTask/Assets.xcassets/Contents.json create mode 100644 MobileInternshipTask/MobileInternshipTask/Base.lproj/LaunchScreen.storyboard create mode 100644 MobileInternshipTask/MobileInternshipTask/Base.lproj/Main.storyboard create mode 100644 MobileInternshipTask/MobileInternshipTask/Info.plist create mode 100644 MobileInternshipTask/MobileInternshipTask/ViewController.swift create mode 100644 MobileInternshipTask/MobileInternshipTaskTests/Info.plist create mode 100644 MobileInternshipTask/MobileInternshipTaskTests/MobileInternshipTaskTests.swift 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..c294ae8 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj @@ -0,0 +1,466 @@ +// !$*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 */; }; +/* 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 = ""; }; +/* 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 = ( + 9246EC852090EDC200F7A40F /* AppDelegate.swift */, + 9246EC872090EDC200F7A40F /* ViewController.swift */, + 9246EC892090EDC200F7A40F /* Main.storyboard */, + 9246EC8C2090EDC200F7A40F /* Assets.xcassets */, + 9246EC8E2090EDC200F7A40F /* LaunchScreen.storyboard */, + 9246EC912090EDC200F7A40F /* Info.plist */, + ); + path = MobileInternshipTask; + sourceTree = ""; + }; + 9246EC992090EDC300F7A40F /* MobileInternshipTaskTests */ = { + isa = PBXGroup; + children = ( + 9246EC9A2090EDC300F7A40F /* MobileInternshipTaskTests.swift */, + 9246EC9C2090EDC300F7A40F /* Info.plist */, + ); + path = MobileInternshipTaskTests; + 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 */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9246EC942090EDC300F7A40F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 9246EC7E2090EDC200F7A40F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9246EC882090EDC200F7A40F /* ViewController.swift in Sources */, + 9246EC862090EDC200F7A40F /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9246EC922090EDC300F7A40F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9246EC9B2090EDC300F7A40F /* MobileInternshipTaskTests.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; + 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; + 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; + 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; + 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/AppDelegate.swift b/MobileInternshipTask/MobileInternshipTask/AppDelegate.swift new file mode 100644 index 0000000..cb99ca9 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// 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 { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/MobileInternshipTask/MobileInternshipTask/Assets.xcassets/AppIcon.appiconset/Contents.json b/MobileInternshipTask/MobileInternshipTask/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/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/Assets.xcassets/Contents.json b/MobileInternshipTask/MobileInternshipTask/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MobileInternshipTask/MobileInternshipTask/Base.lproj/LaunchScreen.storyboard b/MobileInternshipTask/MobileInternshipTask/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f83f6fd --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileInternshipTask/MobileInternshipTask/Base.lproj/Main.storyboard b/MobileInternshipTask/MobileInternshipTask/Base.lproj/Main.storyboard new file mode 100644 index 0000000..03c13c2 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileInternshipTask/MobileInternshipTask/Info.plist b/MobileInternshipTask/MobileInternshipTask/Info.plist new file mode 100644 index 0000000..16be3b6 --- /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 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/MobileInternshipTask/MobileInternshipTask/ViewController.swift b/MobileInternshipTask/MobileInternshipTask/ViewController.swift new file mode 100644 index 0000000..f8a4378 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/ViewController.swift @@ -0,0 +1,25 @@ +// +// ViewController.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 25/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + +} + 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..fabefd8 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTaskTests/MobileInternshipTaskTests.swift @@ -0,0 +1,36 @@ +// +// 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() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} From b69af55316d227fdde3ebd616b76e5436dfeb480 Mon Sep 17 00:00:00 2001 From: dawidramone Date: Mon, 30 Apr 2018 08:22:14 +0200 Subject: [PATCH 02/15] search for repos screen done --- .../project.pbxproj | 44 +++++++- .../Base.lproj/Main.storyboard | 24 ----- .../{ => Controller}/AppDelegate.swift | 0 .../Controller/ReposTableViewController.swift | 42 ++++++++ .../Controller/ViewController.swift | 73 +++++++++++++ .../Model/UserRepos.swift | 83 ++++++++++++++ .../AppIcon.appiconset/Contents.json | 0 .../{ => View}/Assets.xcassets/Contents.json | 0 .../Base.lproj/LaunchScreen.storyboard | 0 .../View/Base.lproj/Main.storyboard | 102 ++++++++++++++++++ .../MobileInternshipTask/ViewController.swift | 25 ----- 11 files changed, 339 insertions(+), 54 deletions(-) delete mode 100644 MobileInternshipTask/MobileInternshipTask/Base.lproj/Main.storyboard rename MobileInternshipTask/MobileInternshipTask/{ => Controller}/AppDelegate.swift (100%) create mode 100644 MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift create mode 100644 MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift create mode 100644 MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift rename MobileInternshipTask/MobileInternshipTask/{ => View}/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename MobileInternshipTask/MobileInternshipTask/{ => View}/Assets.xcassets/Contents.json (100%) rename MobileInternshipTask/MobileInternshipTask/{ => View}/Base.lproj/LaunchScreen.storyboard (100%) create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard delete mode 100644 MobileInternshipTask/MobileInternshipTask/ViewController.swift diff --git a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj index c294ae8..c7d5f5a 100644 --- a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj +++ b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj @@ -13,6 +13,9 @@ 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 */; }; + 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 */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -36,6 +39,8 @@ 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 = ""; }; + 92DD94B72091371C008FD290 /* UserRepos.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRepos.swift; sourceTree = ""; }; + 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReposTableViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -77,11 +82,9 @@ 9246EC842090EDC200F7A40F /* MobileInternshipTask */ = { isa = PBXGroup; children = ( - 9246EC852090EDC200F7A40F /* AppDelegate.swift */, - 9246EC872090EDC200F7A40F /* ViewController.swift */, - 9246EC892090EDC200F7A40F /* Main.storyboard */, - 9246EC8C2090EDC200F7A40F /* Assets.xcassets */, - 9246EC8E2090EDC200F7A40F /* LaunchScreen.storyboard */, + 92DD94B62091243C008FD290 /* Model */, + 92DD94B5209116BE008FD290 /* Controller */, + 92DD94B42091168C008FD290 /* View */, 9246EC912090EDC200F7A40F /* Info.plist */, ); path = MobileInternshipTask; @@ -96,6 +99,34 @@ path = MobileInternshipTaskTests; sourceTree = ""; }; + 92DD94B42091168C008FD290 /* View */ = { + isa = PBXGroup; + children = ( + 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 */, + ); + path = Controller; + sourceTree = ""; + }; + 92DD94B62091243C008FD290 /* Model */ = { + isa = PBXGroup; + children = ( + 92DD94B72091371C008FD290 /* UserRepos.swift */, + ); + path = Model; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -199,6 +230,8 @@ files = ( 9246EC882090EDC200F7A40F /* ViewController.swift in Sources */, 9246EC862090EDC200F7A40F /* AppDelegate.swift in Sources */, + 92DD94B82091371C008FD290 /* UserRepos.swift in Sources */, + 92DD94BC2092507F008FD290 /* ReposTableViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -207,6 +240,7 @@ buildActionMask = 2147483647; files = ( 9246EC9B2090EDC300F7A40F /* MobileInternshipTaskTests.swift in Sources */, + 92DD94BD2092507F008FD290 /* ReposTableViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MobileInternshipTask/MobileInternshipTask/Base.lproj/Main.storyboard b/MobileInternshipTask/MobileInternshipTask/Base.lproj/Main.storyboard deleted file mode 100644 index 03c13c2..0000000 --- a/MobileInternshipTask/MobileInternshipTask/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MobileInternshipTask/MobileInternshipTask/AppDelegate.swift b/MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift similarity index 100% rename from MobileInternshipTask/MobileInternshipTask/AppDelegate.swift rename to MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift new file mode 100644 index 0000000..a0a96bf --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift @@ -0,0 +1,42 @@ +// +// 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]? + let reposCell = "reposCell" + + override func viewDidLoad() { + super.viewDidLoad() +// DispatchQueue.main.async { +// self.tableView.reloadData() +// } + } + + + +// override func numberOfSections(in tableView: UITableView) -> Int { +// return 1 +// } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return repos!.count + } + + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: reposCell, for: indexPath) + cell.textLabel?.text = repos![indexPath.row].name + + + return cell + } + +} diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift new file mode 100644 index 0000000..dd9118b --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift @@ -0,0 +1,73 @@ +// +// 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! + + let repoSegue = "repoSegue" + var reposArray: [UserRepos]? + + + override func viewDidLoad() { + super.viewDidLoad() + } + + override func viewWillAppear(_ animated: Bool) { + reposArray = nil + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any? ) { + if segue.identifier == self.repoSegue { + let reposTableViewController = segue.destination as! ReposTableViewController + reposTableViewController.repos = reposArray + } + } + + @IBAction func findUserButton(_ sender: Any) { + searchForUser() + userNameTxtFiled.text = "" + + } + + func searchForUser() { + guard let user = userNameTxtFiled.text else { return } + let stringUserRepos = "https://api.github.com/users/\(String(describing: user))/repos" + guard let urlUserRepos = URL(string: stringUserRepos) else { return } + URLSession.shared.dataTask(with: urlUserRepos) { (data, response, error) in + guard let data = data, response != nil, error == nil else { return } + do { + let userReposJson = try JSONDecoder().decode([UserRepos].self, from: data) + DispatchQueue.main.async { + self.reposArray = userReposJson + if self.reposArray != nil { + self.performSegue(withIdentifier: self.repoSegue, sender: ViewController.self) + } + } + } catch { + DispatchQueue.main.async { + let alert = UIAlertController(title: "Not Found", message: "Try again", preferredStyle: .alert) + let action = UIAlertAction(title: "OK", style: .default, handler: nil) + alert.addAction(action) + self.present(alert, animated: true, completion: nil) + } + } + }.resume() + + } + +} + + + + + + + + diff --git a/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift b/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift new file mode 100644 index 0000000..680e6f8 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift @@ -0,0 +1,83 @@ +// +// UserRepos.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 26/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation + +struct UserRepos: Decodable { + let id: Int? + let name: String? + let full_name: String? +// let owner: Owner +// let private: String + let html_url: String? + let description: String? + let fork: Bool? + let url: String? + let forks_url: String? + let keys_url: String? + let collaborators_url: String? + let teams_url: String? + let hooks_url: String? + let issue_events_url: String? + let events_url: String? + let assignees_url: String? + let branches_url: String? + let tags_url: String? + let blobs_url: String? + let git_tags_url: String? + let git_refs_url: String? + let trees_url: String? + let statuses_url: String? + let languages_url: String? + let stargazers_url: String? + let contributors_url: String? + let subscribers_url: String? + let subscription_url: String? + let commits_url: String? + let git_commits_url: String? + let comments_url: String? + let issue_comment_url: String? + let contents_url: String? + let compare_url: String? + let merges_url: String? + let archive_url: String? + let downloads_url: String? + let issues_url: String? + let pulls_url: String? + let milestones_url: String? + let notifications_url: String? + let labels_url: String? + let releases_url: String? + let deployments_url: String? + let created_at: String? + let updated_at: String? + let pushed_at: String? + let git_url: String? + let ssh_url: String? + let clone_url: String? + let svn_url: String? +// let homepage: Homepage + let size: Int? + let stargazers_count: Int? + let watchers_count: Int? + let language: String? + let has_issues: Bool? + let has_projects: Bool? + let has_downloads: Bool? + let has_wiki: Bool? + let has_pages: Bool? + let forks_count: Int? +// let mirror_url: Mirror_url + let archived: Bool? + let open_issues_count: Int? +// let license: License + let forks: Int? + let open_issues: Int? + let watchers: Int? + let default_branch: String? +} diff --git a/MobileInternshipTask/MobileInternshipTask/Assets.xcassets/AppIcon.appiconset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from MobileInternshipTask/MobileInternshipTask/Assets.xcassets/AppIcon.appiconset/Contents.json rename to MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/MobileInternshipTask/MobileInternshipTask/Assets.xcassets/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/Contents.json similarity index 100% rename from MobileInternshipTask/MobileInternshipTask/Assets.xcassets/Contents.json rename to MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/Contents.json diff --git a/MobileInternshipTask/MobileInternshipTask/Base.lproj/LaunchScreen.storyboard b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from MobileInternshipTask/MobileInternshipTask/Base.lproj/LaunchScreen.storyboard rename to MobileInternshipTask/MobileInternshipTask/View/Base.lproj/LaunchScreen.storyboard diff --git a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard new file mode 100644 index 0000000..2bbdf0b --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MobileInternshipTask/MobileInternshipTask/ViewController.swift b/MobileInternshipTask/MobileInternshipTask/ViewController.swift deleted file mode 100644 index f8a4378..0000000 --- a/MobileInternshipTask/MobileInternshipTask/ViewController.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// ViewController.swift -// MobileInternshipTask -// -// Created by Dawid Ramone on 25/04/2018. -// Copyright © 2018 Dawid Czmyr. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - -} - From d81e8048eddcbfdb4935a5e939906fac5a77a0ad Mon Sep 17 00:00:00 2001 From: dawidramone Date: Mon, 30 Apr 2018 18:52:30 +0200 Subject: [PATCH 03/15] add registerCell(), setUserNameInNav() --- .../project.pbxproj | 20 ++++++ .../Controller/ReposTableViewController.swift | 56 +++++++++++---- .../Controller/ViewController.swift | 14 ++-- .../MobileInternshipTask/Info.plist | 4 +- .../MobileInternshipTask/Model/Owner.swift | 29 ++++++++ .../Model/UserRepos.swift | 4 +- .../View/Base.lproj/Main.storyboard | 13 +--- .../View/ReposCell/ReposCell.swift | 19 +++++ .../View/ReposCell/ReposCell.xib | 71 +++++++++++++++++++ 9 files changed, 192 insertions(+), 38 deletions(-) create mode 100644 MobileInternshipTask/MobileInternshipTask/Model/Owner.swift create mode 100644 MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.swift create mode 100644 MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib diff --git a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj index c7d5f5a..97d7d3a 100644 --- a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj +++ b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj @@ -13,6 +13,9 @@ 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 */; }; + 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 */; }; 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 */; }; @@ -39,6 +42,9 @@ 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 = ""; }; + 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 = ""; }; 92DD94B72091371C008FD290 /* UserRepos.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRepos.swift; sourceTree = ""; }; 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReposTableViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -99,9 +105,19 @@ path = MobileInternshipTaskTests; 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 */, @@ -123,6 +139,7 @@ isa = PBXGroup; children = ( 92DD94B72091371C008FD290 /* UserRepos.swift */, + 9298226320970B0800837D92 /* Owner.swift */, ); path = Model; sourceTree = ""; @@ -211,6 +228,7 @@ 9246EC902090EDC200F7A40F /* LaunchScreen.storyboard in Resources */, 9246EC8D2090EDC200F7A40F /* Assets.xcassets in Resources */, 9246EC8B2090EDC200F7A40F /* Main.storyboard in Resources */, + 929822692097127200837D92 /* ReposCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -231,7 +249,9 @@ 9246EC882090EDC200F7A40F /* ViewController.swift in Sources */, 9246EC862090EDC200F7A40F /* AppDelegate.swift in Sources */, 92DD94B82091371C008FD290 /* UserRepos.swift in Sources */, + 9298226420970B0800837D92 /* Owner.swift in Sources */, 92DD94BC2092507F008FD290 /* ReposTableViewController.swift in Sources */, + 929822682097127200837D92 /* ReposCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift index a0a96bf..c779021 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift @@ -9,34 +9,60 @@ import UIKit class ReposTableViewController: UITableViewController { - + var repos : [UserRepos]? let reposCell = "reposCell" + override func viewDidLoad() { super.viewDidLoad() -// DispatchQueue.main.async { -// self.tableView.reloadData() -// } - } + userDoesntHaveRepos() + setUserNameInNav() + registerCell() + - - -// override func numberOfSections(in tableView: UITableView) -> Int { -// return 1 -// } + } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return repos!.count + guard let repos = repos else { return 0 } + return repos.count } - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: reposCell, for: indexPath) - cell.textLabel?.text = repos![indexPath.row].name + 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 + } + func userDoesntHaveRepos() { + if repos?.isEmpty == true { + let alert = UIAlertController(title: "Oops looks like user exist but doesn't have any repos", message: "Try again", preferredStyle: .alert) + let action = UIAlertAction(title: "OK", style: .default) { (UIAlertAction) -> Void in + self.navigationController?.popViewController(animated: true) + } + alert.addAction(action) + self.present(alert, animated: true, completion: nil) - return cell + } + } + + func setUserNameInNav() { + if repos?.isEmpty == false { + if let owner = repos { + navigationItem.title = owner[0].owner?.login + } + } + + } + + 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 index dd9118b..548fbd7 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift @@ -24,16 +24,15 @@ class ViewController: UIViewController { } override func prepare(for segue: UIStoryboardSegue, sender: Any? ) { - if segue.identifier == self.repoSegue { - let reposTableViewController = segue.destination as! ReposTableViewController - reposTableViewController.repos = reposArray + if segue.identifier == self.repoSegue { + let reposTableViewController = segue.destination as! ReposTableViewController + reposTableViewController.repos = reposArray } } @IBAction func findUserButton(_ sender: Any) { - searchForUser() - userNameTxtFiled.text = "" - + searchForUser() + userNameTxtFiled.text = "" } func searchForUser() { @@ -52,14 +51,13 @@ class ViewController: UIViewController { } } catch { DispatchQueue.main.async { - let alert = UIAlertController(title: "Not Found", message: "Try again", preferredStyle: .alert) + let alert = UIAlertController(title: "User not found", message: "Try again", preferredStyle: .alert) let action = UIAlertAction(title: "OK", style: .default, handler: nil) alert.addAction(action) self.present(alert, animated: true, completion: nil) } } }.resume() - } } diff --git a/MobileInternshipTask/MobileInternshipTask/Info.plist b/MobileInternshipTask/MobileInternshipTask/Info.plist index 16be3b6..716d1ca 100644 --- a/MobileInternshipTask/MobileInternshipTask/Info.plist +++ b/MobileInternshipTask/MobileInternshipTask/Info.plist @@ -28,11 +28,11 @@ armv7 + UIRequiresFullScreen + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad diff --git a/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift b/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift new file mode 100644 index 0000000..a25bb97 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift @@ -0,0 +1,29 @@ +// +// Owner.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 30/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import Foundation + +struct Owner: Codable { + let login: String? + let id: Int? + let avatar_url: String? +// let gravatar_id: String + let url: String? + let html_url: String? + let followers_url: String? + let following_url: String? + let gists_url: String? + let starred_url: String? + let subscriptions_url: String? + let organizations_url: String? + let repos_url: String? + let events_url: String? + let received_events_url: String? +// let type: String + let site_admin: Bool? +} diff --git a/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift b/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift index 680e6f8..ac551ef 100644 --- a/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift +++ b/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift @@ -8,11 +8,11 @@ import Foundation -struct UserRepos: Decodable { +struct UserRepos: Codable { let id: Int? let name: String? let full_name: String? -// let owner: Owner + let owner: Owner? // let private: String let html_url: String? let description: String? diff --git a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard index 2bbdf0b..bbb5f73 100644 --- a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard +++ b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard @@ -60,16 +60,7 @@ - - - - - - - - - - + @@ -78,7 +69,7 @@ - + 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..bdef7ce --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From c6081abcd0394ea539446f37bc1fc4051846a817 Mon Sep 17 00:00:00 2001 From: dawidramone Date: Mon, 30 Apr 2018 21:17:21 +0200 Subject: [PATCH 04/15] add DetailRepoViewController --- .../project.pbxproj | 6 ++++ .../Controller/DetailRepoViewController.swift | 19 +++++++++++ .../Controller/ReposTableViewController.swift | 26 ++++++++++++--- .../Controller/ViewController.swift | 8 +++++ .../gitHubLogo.imageset/Contents.json | 21 ++++++++++++ .../gitHubLogo.imageset/gitHubLogo.png | Bin 0 -> 1592 bytes .../View/Base.lproj/Main.storyboard | 31 ++++++++++++++++-- 7 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/Contents.json create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/gitHubLogo.png diff --git a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj index 97d7d3a..61c12dd 100644 --- a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj +++ b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ 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 */; }; 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 */; }; @@ -45,6 +47,7 @@ 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 = ""; }; 92DD94B72091371C008FD290 /* UserRepos.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRepos.swift; sourceTree = ""; }; 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReposTableViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -131,6 +134,7 @@ 9246EC852090EDC200F7A40F /* AppDelegate.swift */, 9246EC872090EDC200F7A40F /* ViewController.swift */, 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */, + 9298226A20979C7800837D92 /* DetailRepoViewController.swift */, ); path = Controller; sourceTree = ""; @@ -249,6 +253,7 @@ 9246EC882090EDC200F7A40F /* ViewController.swift in Sources */, 9246EC862090EDC200F7A40F /* AppDelegate.swift in Sources */, 92DD94B82091371C008FD290 /* UserRepos.swift in Sources */, + 9298226B20979C7800837D92 /* DetailRepoViewController.swift in Sources */, 9298226420970B0800837D92 /* Owner.swift in Sources */, 92DD94BC2092507F008FD290 /* ReposTableViewController.swift in Sources */, 929822682097127200837D92 /* ReposCell.swift in Sources */, @@ -260,6 +265,7 @@ buildActionMask = 2147483647; files = ( 9246EC9B2090EDC300F7A40F /* MobileInternshipTaskTests.swift in Sources */, + 9298226C20979C7800837D92 /* DetailRepoViewController.swift in Sources */, 92DD94BD2092507F008FD290 /* ReposTableViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift new file mode 100644 index 0000000..cba0628 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift @@ -0,0 +1,19 @@ +// +// DetailRepoViewController.swift +// MobileInternshipTask +// +// Created by Dawid Ramone on 30/04/2018. +// Copyright © 2018 Dawid Czmyr. All rights reserved. +// + +import UIKit + +class DetailRepoViewController: UIViewController { + var userRepo: UserRepos? + + override func viewDidLoad() { + super.viewDidLoad() + } + + +} diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift index c779021..a3ec941 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift @@ -10,8 +10,10 @@ import UIKit class ReposTableViewController: UITableViewController { - var repos : [UserRepos]? + var repos: [UserRepos]? + var singleRepo: UserRepos? let reposCell = "reposCell" + let detailRepo = "detailRepo" override func viewDidLoad() { @@ -22,6 +24,12 @@ class ReposTableViewController: UITableViewController { } + 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 } @@ -35,10 +43,17 @@ class ReposTableViewController: UITableViewController { 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 { let alert = UIAlertController(title: "Oops looks like user exist but doesn't have any repos", message: "Try again", preferredStyle: .alert) @@ -53,11 +68,12 @@ class ReposTableViewController: UITableViewController { func setUserNameInNav() { if repos?.isEmpty == false { - if let owner = repos { - navigationItem.title = owner[0].owner?.login + if let repos = repos { + if let owner = repos[0].owner?.login { + navigationItem.title = owner + "'s repositories" + } } } - } func registerCell() { diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift index 548fbd7..f1d1a0a 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift @@ -17,6 +17,7 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + addNavBarImage() } override func viewWillAppear(_ animated: Bool) { @@ -60,6 +61,13 @@ class ViewController: UIViewController { }.resume() } + func addNavBarImage() { + let image = #imageLiteral(resourceName: "gitHubLogo") + let imageView = UIImageView(image: image) + imageView.contentMode = .scaleAspectFit + navigationItem.titleView = imageView + } + } diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/Contents.json new file mode 100644 index 0000000..6d73b14 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "gitHubLogo.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/gitHubLogo.imageset/gitHubLogo.png b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/gitHubLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..7063706151c48378116ce15989fa044a8b4e0148 GIT binary patch literal 1592 zcmV-82FLk{P)hK~#90?U`MSBvlp1f2XF`{ite*GgEbYht?fHc@PbRk1Sby5l~`; zWI;nTpd>^?ln@Ca@L(bs))3+YyAsrxD3K6&@GHgy{2(N{5;ust2qS1#L*g>sRn^Nd zOxF%Wch~V@X5-AzRb73%XMM1KPu+EH{qMd1syaD!3Q9^!N=iyfN=iyf{vVP5#iX;d zvpbfTmv^t5U#r#X{IO%lR!;X?PKyD)@7E^aQ;1xS>LrNO`^>Gtzkxpj_c!!V4t zdTm>3fHCG$RPPeF2B-{qdI$Igj`KjX*?evbmIrK+0lx3Qf5LGNqWZ~k=n4Eh6}ck} z!+(uKZ}!`hg@fv>9Smw;{ShIJ8H0zkFO#=Ox5zSm9D1Fcr80Z{Y(ClL9}rX?&^ zdcE_GpE&WF?H)!-R-$^4O`8W$`2DHhYsJi0W~QdTlRC~7j>yrD>I-okx7VNJ`@Xjg zE=b{gsZ^e6G#W2&l6@A~Y`_`aO65V|dh0#do@k8OE2>BO#Z=^mFbp5J)$YgcAo!fZ zqy46vP`&WAI6i8lYx``1>fKo(Nz+Md-AqxL%8GPF?zEM)GGJzAW?JCt%mE^o*e)mw zRlP8CI@s^~zGtIrWk9dj+t0>?ww{iYriW~F^H7m*0?Qd;w<2X&+&7lpb*Xui3EpGa;9ERcZ zHVY|26h$urCo{qyu+bdafKI1V%Q>$J^lTPVkQ4|rVv|@@wlFIYAWrG;n01?T%!qda*4LyJM9BPaix~FJ!2gEtC9n;g(yDc;e;ro6K*xoOuusAn2 z_x7-wLmSX+HeV;_Ij@L(d|1t*R75_O6?5`0OeQvWKo9t5W>n;}HVY|&s^-1){LMzw zst!>2ZBF>ATCHYPl;klJ1eYO_U4FywY;>&*aPkd+G<_@xf^%%N`*G&vWIct)2F!W- z4A{1^@+8>>3BZg4hl3!AobB6t+(Q5t4M&GI>wz#tLmg~BE1TF$V zWC6HepaGoAYNMqpaAVbVFLOPw>v>+3BuP?4KL`TzZr9!Kx$c7k_Wi&r&+DcHmnnPRnqkOMyu7gTsFpBDymNadxlus z;!3BpXJKJs(Pkgk4UsSmUlP^tul*I^>osEz&ByUyP`#0NwyZ_q4_TXE(>%gzIbHa| zsOr~jHxHw9gn)_d+wTVc`vFt+He<{c%{YEaMDAd98!j4@Y=>Tfc_iz@QzK^ns_QV!TmGmak?)vJN|b%z7s zZ1VdEMR*R!**DJ3!KXvFa^S2~>!0^ep`avXsr6}i0`Mf;k~rqv5i9%DBEU}0fl zu^C0TI=$X`s(Ns(Qe+}cPYgO&MCMt|>~pBz_I9^h55w>fTia^eTI%)s&id5UnMKFj qe&i@ADJdx_DJdx_DJdx_$bSIGzV^;qLjAb_0000 - + @@ -66,10 +66,37 @@ + + + - + + + + + + + + + + + + + + + + + + + From 90f3481e91e226b2e818f3cb0a5c091fe25f3cf5 Mon Sep 17 00:00:00 2001 From: dawidramone Date: Tue, 1 May 2018 12:26:27 +0200 Subject: [PATCH 05/15] add loadActivityIndicator(), stopLoadingActivityIndicator() --- .../Controller/ReposTableViewController.swift | 3 --- .../Controller/ViewController.swift | 22 ++++++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift index a3ec941..34ce980 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift @@ -15,14 +15,12 @@ class ReposTableViewController: UITableViewController { let reposCell = "reposCell" let detailRepo = "detailRepo" - override func viewDidLoad() { super.viewDidLoad() userDoesntHaveRepos() setUserNameInNav() registerCell() - } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == detailRepo { @@ -80,5 +78,4 @@ class ReposTableViewController: UITableViewController { 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 index f1d1a0a..75e6633 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift @@ -13,8 +13,9 @@ class ViewController: UIViewController { let repoSegue = "repoSegue" var reposArray: [UserRepos]? + var activityIndicator:UIActivityIndicatorView = UIActivityIndicatorView() + - override func viewDidLoad() { super.viewDidLoad() addNavBarImage() @@ -34,6 +35,7 @@ class ViewController: UIViewController { @IBAction func findUserButton(_ sender: Any) { searchForUser() userNameTxtFiled.text = "" + loadActivityIndicator() } func searchForUser() { @@ -47,6 +49,7 @@ class ViewController: UIViewController { DispatchQueue.main.async { self.reposArray = userReposJson if self.reposArray != nil { + self.stopLoadingActivityIndicator() self.performSegue(withIdentifier: self.repoSegue, sender: ViewController.self) } } @@ -68,6 +71,23 @@ class ViewController: UIViewController { navigationItem.titleView = imageView } + func loadActivityIndicator() { + activityIndicator.center = self.view.center + activityIndicator.hidesWhenStopped = true + activityIndicator.activityIndicatorViewStyle = .gray + view.addSubview(activityIndicator) + + activityIndicator.startAnimating() + UIApplication.shared.beginIgnoringInteractionEvents() + } + + func stopLoadingActivityIndicator() { + DispatchQueue.main.async { + self.activityIndicator.stopAnimating() + UIApplication.shared.endIgnoringInteractionEvents() + } + + } } From a081e2c5545a6027b1ac196f1f6eca0010771a65 Mon Sep 17 00:00:00 2001 From: dawidramone Date: Wed, 2 May 2018 13:24:33 +0200 Subject: [PATCH 06/15] add checkConnectionToNetwork() --- .../project.pbxproj | 6 + .../Controller/ConnectedToNetwork.swift | 46 +++++ .../Controller/DetailRepoViewController.swift | 45 ++++- .../Controller/ReposTableViewController.swift | 21 +- .../Controller/ViewController.swift | 20 +- .../Contents.json | 2 +- .../background.imageset/background.png | Bin 0 -> 8690 bytes .../button01.imageset/Contents.json | 21 ++ .../button01.imageset/button01.png | Bin 0 -> 6826 bytes .../gitHubLogo.imageset/gitHubLogo.png | Bin 1592 -> 0 bytes .../logo_github_white.imageset/Contents.json | 21 ++ .../logo_github_white.png | Bin 0 -> 5157 bytes .../logo_turkus.imageset/Contents.json | 21 ++ .../logo_turkus.imageset/logo_turkus.png | Bin 0 -> 3445 bytes .../Contents.json | 21 ++ .../see_full_details_button.png | Bin 0 -> 5209 bytes .../View/Base.lproj/Main.storyboard | 179 +++++++++++++++--- .../View/ReposCell/ReposCell.xib | 32 ++-- 18 files changed, 383 insertions(+), 52 deletions(-) create mode 100644 MobileInternshipTask/MobileInternshipTask/Controller/ConnectedToNetwork.swift rename MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/{gitHubLogo.imageset => background.imageset}/Contents.json (87%) create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/background.png create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/button01.imageset/Contents.json create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/button01.imageset/button01.png delete mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/gitHubLogo.png create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_github_white.imageset/Contents.json create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_github_white.imageset/logo_github_white.png create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_turkus.imageset/Contents.json create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/logo_turkus.imageset/logo_turkus.png create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/see_full_details_button.imageset/Contents.json create mode 100644 MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/see_full_details_button.imageset/see_full_details_button.png diff --git a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj index 61c12dd..7eeac63 100644 --- a/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj +++ b/MobileInternshipTask/MobileInternshipTask.xcodeproj/project.pbxproj @@ -13,6 +13,8 @@ 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 */; }; 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 */; }; @@ -44,6 +46,7 @@ 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 = ""; }; 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 = ""; }; @@ -135,6 +138,7 @@ 9246EC872090EDC200F7A40F /* ViewController.swift */, 92DD94BB2092507F008FD290 /* ReposTableViewController.swift */, 9298226A20979C7800837D92 /* DetailRepoViewController.swift */, + 9266F43B2098E891005F6A24 /* ConnectedToNetwork.swift */, ); path = Controller; sourceTree = ""; @@ -253,6 +257,7 @@ 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 */, 9298226420970B0800837D92 /* Owner.swift in Sources */, 92DD94BC2092507F008FD290 /* ReposTableViewController.swift in Sources */, @@ -267,6 +272,7 @@ 9246EC9B2090EDC300F7A40F /* MobileInternshipTaskTests.swift in Sources */, 9298226C20979C7800837D92 /* DetailRepoViewController.swift in Sources */, 92DD94BD2092507F008FD290 /* ReposTableViewController.swift in Sources */, + 9266F43D2098E891005F6A24 /* ConnectedToNetwork.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ConnectedToNetwork.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ConnectedToNetwork.swift new file mode 100644 index 0000000..9aa05d6 --- /dev/null +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ConnectedToNetwork.swift @@ -0,0 +1,46 @@ +// +// 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 + } + + /* Only Working for WIFI + let isReachable = flags == .reachable + let needsConnection = flags == .connectionRequired + + return isReachable && !needsConnection + */ + + // Working for Cellular and WIFI + 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/DetailRepoViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift index cba0628..7d4f065 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift @@ -9,11 +9,54 @@ 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? override func viewDidLoad() { super.viewDidLoad() + roundedCorners() + setupLabels() + } + + func setupLabels() { + if let userRepos = userRepo { + repoNameLabel.text = userRepos.name + descriptionLabel.text = userRepos.description + languageLabel.text = userRepos.language + } } - + @IBAction func seeDetailsButton(_ sender: Any) { + if let date = userRepo?.updated_at { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + let datedate = dateFormatter.date(from: date) + print(datedate!) + } + } + + func roundedCorners() { + repoNameLabel.layer.cornerRadius = 10.0 + repoNameLabel.clipsToBounds = true + descriptionLabel.layer.cornerRadius = 10.0 + descriptionLabel.clipsToBounds = true + languageLabel.layer.cornerRadius = 10.0 + languageLabel.clipsToBounds = true + createdLabel.layer.cornerRadius = 10.0 + createdLabel.clipsToBounds = true + updatedLabel.layer.cornerRadius = 10.0 + updatedLabel.clipsToBounds = true + watchersLabel.layer.cornerRadius = 10.0 + watchersLabel.clipsToBounds = true + forksLabel.layer.cornerRadius = 10.0 + forksLabel.clipsToBounds = true + } + } diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift index 34ce980..3084323 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift @@ -19,8 +19,7 @@ class ReposTableViewController: UITableViewController { super.viewDidLoad() userDoesntHaveRepos() setUserNameInNav() - registerCell() - + registerCell() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == detailRepo { @@ -67,8 +66,22 @@ class ReposTableViewController: UITableViewController { func setUserNameInNav() { if repos?.isEmpty == false { if let repos = repos { - if let owner = repos[0].owner?.login { - navigationItem.title = owner + "'s repositories" + 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 image = image + let imageView = UIImageView(image: image) + imageView.contentMode = .scaleAspectFit + self.navigationItem.titleView = imageView + } + } + }.resume() } } } diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift index 75e6633..0da840f 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift @@ -10,6 +10,7 @@ import UIKit class ViewController: UIViewController { @IBOutlet weak var userNameTxtFiled: UITextField! + @IBOutlet weak var findUserOutlet: UIButton! let repoSegue = "repoSegue" var reposArray: [UserRepos]? @@ -18,6 +19,7 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + checkConnectionToNetwork() addNavBarImage() } @@ -54,6 +56,7 @@ class ViewController: UIViewController { } } } catch { + self.stopLoadingActivityIndicator() DispatchQueue.main.async { let alert = UIAlertController(title: "User not found", message: "Try again", preferredStyle: .alert) let action = UIAlertAction(title: "OK", style: .default, handler: nil) @@ -65,7 +68,7 @@ class ViewController: UIViewController { } func addNavBarImage() { - let image = #imageLiteral(resourceName: "gitHubLogo") + let image = #imageLiteral(resourceName: "logo_turkus") let imageView = UIImageView(image: image) imageView.contentMode = .scaleAspectFit navigationItem.titleView = imageView @@ -74,7 +77,7 @@ class ViewController: UIViewController { func loadActivityIndicator() { activityIndicator.center = self.view.center activityIndicator.hidesWhenStopped = true - activityIndicator.activityIndicatorViewStyle = .gray + activityIndicator.activityIndicatorViewStyle = .whiteLarge view.addSubview(activityIndicator) activityIndicator.startAnimating() @@ -86,8 +89,19 @@ class ViewController: UIViewController { self.activityIndicator.stopAnimating() UIApplication.shared.endIgnoringInteractionEvents() } - } + + func checkConnectionToNetwork() { + if Reachability.isConnectedToNetwork() == false { + let alert = UIAlertController(title: "No Internet connection", message: "Try again", preferredStyle: .alert) + let action = UIAlertAction(title: "OK", style: .default, handler: nil) + alert.addAction(action) + self.present(alert, animated: true, completion: nil) + findUserOutlet.isEnabled = false + + } + } + } diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/Contents.json b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/Contents.json similarity index 87% rename from MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/Contents.json rename to MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/Contents.json index 6d73b14..790c09f 100644 --- a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/Contents.json +++ b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/background.imageset/Contents.json @@ -2,7 +2,7 @@ "images" : [ { "idiom" : "universal", - "filename" : "gitHubLogo.png", + "filename" : "background.png", "scale" : "1x" }, { 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 0000000000000000000000000000000000000000..f43a5ef09b1feb50cfb33325f7895897ace05547 GIT binary patch literal 8690 zcmeHLU1%It6uz1e+uDSHFIA`xQ~M|G&QE4{cBWaI-JM;#(2XHoFzADs%-$qpvNO}! zNp}+vg9JtNO;o7Z2NA)Sf*@7!!P2VWyPyUYiwZuN>O=LV2;RH9ce)p5GrO3FCQM#3 zd$`{@_nh8pg@-6i5K`%e!owMh? zy6!@dsn~OnDOU9bI1Tm6>iMtXI6_s-@{BiAI;$FXHLl||@kZ4_XaL4fHyqtqf*vym z7fdV7{`uMGEMr#E?9+)7UvhGA(LA%}!gFhrWn*p0P%7-{Cz$buiWF3#r!$S}vQ<+X zX|}0XMc-J=u}pJ`x0GgEo0=(2F*)0XOd_6)8G^(!vJw}Pyp#|gXGC6*IX=Ph$rvxF zd`cAsrv1kvYi?y;oz@C%Tj*DsUGzLh<+ysi90!Fdh-Vk1hcB4M!nkXsyvSu4ARcLudEzPFnyr^hN zQILduAu*;Xl9)=#N}`Yz3zDoP3APi1w8blCMdc+iA=+MccD$i?+k$ayZi|=0r(1ObZK7 z;^ee^)u3x$fR%!4SD9vXRWo20DLE@ExvZw-cquOnLMkaMc`ZAZ(Z&QhDk|hDGnbCPf9jcIAArq?4QJ}*=PsVS@!p%iT{(Pv5P)xz@1Rq-aS8zDhkL-p zrvm_7I}E_+&6WV%7y)2ky(L(8?gPF6FKr68#}Z}Tu~@rrmndtR3B=-^`E~=bzOwF4 zU^4{kE9)MBz>Rbdz)m<9Lry?MH>uD|u|5CBup-oF0A){mp;>-#r8JSw2cu6*IAw;w^X)rqarr7ylj zc^z7;)`!o`Td8`ZHvcw zJ&z{Z*U?Kh7F@;8@kB6-$~P8(uh4e6h20S+r~vGQ6I1~FXm)0zUne@TJ!CQ535o%MndsArCVPn8@GSP=1jT?rI`!!U zMdMzmcodx~VmL};R8iU`l~97>6UD_{Ur}BgJOnPjd;FE}7XJPR_m*OQQoEd;ed#|} CaF9*_ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d136c57386c58d08f32c85c3e4371badac61f523 GIT binary patch literal 6826 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 H+_?RJwI{pJ literal 0 HcmV?d00001 diff --git a/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/gitHubLogo.png b/MobileInternshipTask/MobileInternshipTask/View/Assets.xcassets/gitHubLogo.imageset/gitHubLogo.png deleted file mode 100644 index 7063706151c48378116ce15989fa044a8b4e0148..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1592 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ba1b33b8b34d634761bccf11e0eb3d5af19a7fa1 GIT binary patch literal 5209 zcmbU_c|4SB+v6y_g~*8#VVpJ@vlzyVeHn5x#EftdgR#WSV8$}mIw?g_MmfP02(Lk`;;Q#_($*X#rH8 zUIbgZEzS(%N+qihc{nP;WM6<91k%zC_9eP{lj!m;Bo8l&Hh8Y84lM8GrVX}H!@+RA zh9pm~lOg^je26*0HN@K$?FQD>k=F{w01U_^I#E8D>_eepg0;chd@;Z??-&Y}-$tQ( zYlFWjWs5s4Z%Fkg$*ZZTLtNoVm^=!t0#}D2)!@qV2pAj%g{eVd>JS(l1Jl4D;PT&p zU_hF`n>)tJ$oRV~V5bfCq|<#dP-sw4kV=rM3f12O3P+>SP#6M=KtKQt2#rCZ6N4cX zn&J-*MkJc6zn3rFi%OB_aU{A>1L)ddK+|s~kbQBuzZg?!-yH?G3>r-Ig~C-}P%@ck z*ETkdZbkZ!8vlq*BQShPP%9FR8sP5=#KT?j2QlEg|1OA!2xx<`@b?0OLi91Bx(1L* z6uPOAHdq6NMWBt;5pX0NYpkYryui9)OYp#3`yz)i)?%MF87!@^;z zSTqueG=#&k8X9Odw2^@^QUi@PM(JaXf6$szXmldQmBf?BqxJd^t;T<)#TfdNh;*ty zflBrH5&6@eR63RBN%fUCG~`8EL;e_!=;}q`9UkWe=bNoYB!90!lAEzVl`OyQU5wX1 zXyHymtGT1xi4Y>u1r9+HN$wC0B+M1!s_y2Ba&v>ZySSpj-|5}{=CvOlfWr+{jS)zF zGz^BsqTp~1brc$FWT2{VqzXqFAk@K7Kp`kEJ^q$1KaPMLqDXdcg7#M z9Q6aP7!XJ-+SEv&5ZpgK=yy$~$5C+pIytSlV&sIn_7y{XW1_Gv?%k1dq=XJ6`2l#r z#3~DWZaq?rAaq(h2Uz99S{`xYF z9R2DS$Xr=jsLzUfpofQtyGM|&+~?y9eN|M>%s>T)$(U=~*LYWVD5vQzA?|_yDWzyU z`bIOCa0YMp8MybYLoW&HR*b`mZ*$Vj*cAlx2mZBjyMnC0hV?vL^v(&>O5BtA^sNU_ zdy0F1%{RKeR$t#fY{s6$uZ1W%onlv6TbJL@7++%(xXOu1R%dZ2U@V{*{V@9=4=k0ky});qyPfdBL?2KnA}Xr%f&=FCNw)e zSUfNz3fs_1Q%jBmEKZ^x zF1mTNE^Ja>YVQ7fXcd z)bzFLZNB4lwJ-6$bv`GrWU6#?x-*qZzl+&OFVUi$RbJn)H_}lBSlTx5jSPBkXxhxR z>b4q#yzPZHzLfNM)Uy2ed!ELpO2u-y{mSNU!d1x)gtQm)clZqUgB&@V@1L=l8xh8a zdOLMEcc0%OPClDUd#6$V{^=3ndj@_x%|QGhW52_~_rUOFSf>0ZbfI4~$-+9fZmvX~@CjOT(q5K_(~DF$n1}{OdX` zGRAQ$#@srf?I}x1H~k_%Ud#re&bDo`OOhB}Y6-D;-aZgCSrU6GkkI-Fnx9A7q6`MN z-JRXyY&aHEi)qDOpSLOqE!V@RCYKf*ysPrpw{*vIEn8F7HEp+k$rw_6ykV7I6Ec7) zjtHf2IaWDyetoHG?NfgHZAEQlLb(iy^ab{ZU-uWE z7WQd=KaUa+hTE<-bIkWen0?)7&*Iz4E*i5NU4Gg3L9p|@d#7q=QMN>LSQ*$eEF$J! zO?J4>S(_cTrVULau8QT_!IN%}^QF}oG6J{b)rcL4h27PyQ0_B6^EZu2vin7KxZEJQ z6i<2eSPZdq?v-zPDi-AJogU8-=OewFLTkHE`fMqsjKKn=>T z*n7me%HKlaKCx=NFLghCaVxj_!UyN@RBxRXcXQ2{y4W6vFS&EdlewpIPaQ}*)a!H< zkzIG>NXuak=A2nw`^T&83ol+(JgE)p(d1B{Y~4A759fBCj=Z)^w3}1-sT0ZRi_uHA z*&3UI2E}V{*2>PY^XO^KAr=cotF^^5p&eiR_KP)~KhUB{la8&C(^(oV)pz~+d*sLY zwgCYUmQ~(ZnS9J{lrfCxttwb6s#ZI?P$?*Qg#4(;9G)!e;IwzD{IXzb)@80pk@%lV zbIom~%l{HFn5P04)F_Mf8m`KM$(IWW@Np5}BG+7progeJZ~$=WcoQ#fS#gS^M1cKPD2y zHI57hyWHFe8!9|9)Sj*8ZNYSG_i1FLoN;K}HfQH<&-)*lZE>p8W0|Wj>GyM=5q&HM zOEC&BUP;T?yR5Pqm)H-d?OJkCBLb3JHJrx zv&PlLhANV-=9pszh;WEUa72;YsDxn0 z2u&L_h->;>{-0I6dVm^CZVa%($!#7Lv=6Cq_$~&lJZ^FEv~Wme~S> zW!6YOY#$%Is640L2q*W4=0Tos$4Bx?QK99i)Y>oj2$%E7&$p7n0|7no*M8~wqm}&i zyYFwc#kBpTWWyE^j_nwa-BFNyTZ*Wvu5fiZ2u`978T2a0JqLkAJ}Rr^gUPdXS=oNFA1D(_~5=TEOp#`cbz3_>9kJ=w!2 z&O=6Avg{F&9~U-w7M?%#xq=xj%p^uTkhnF#_2$ zQ&Y`QygHS7g4nT_!T(h8ai|G*v@Vn!xuO^GBIR24396poR@I*CGW3=9pOYAoxE^$w zg7SFL!7fqp`rA3zkL(umP#q|)d$^iiU_}?KS6^AHjvzEz=Tvj{HfA$0=#G!uQB)VM zrsYMvxU-sj!9}=Z)IGz_8{!huTCO^1kz1FhnH)0FfxDx52g`&9r@74|rZD5yvm=}J ze^MeR_JrJT8?7~3s$6owyA)kf7Jr%{?9?<7S(jPU0B_OJos60Eg~f2}KE_y|&Ay^8 zBkHo?uyAPHOT^(V;5$Y|geZB9oi2b{*sbX;_A`H)##`y#n`2TN{j-maRp^mgB40;` zuOIx_nCEE6AIt5V$}T&}T;LS$quq3VLuW1>Y+!k;T=L9{@V!@_92h)4RMN`*c@r+s zSIAsnXZP$T>*|;$-?dJUua|60%oY22jx(XT5-@drKw7w)(O#A=+XpTB-L*PN$l(p^ z&1FA!_UpuIzbP51O%31$uD4q&?9)q@VlMPv(La zHfyjogT)XP35?HW$%V}kX1ktPhWr0kG`&=4Pt1j+W)A7YOP0QPZ>T;u(HhSF%(Uw- zCq?pXNAvP#uLn+UmDSYwcG~6qm-?vK71tYQ0zLABYv9fY$}02^PNp^1&d;BMnj z%S6`r#}LE$N|`mRN9~Q)%l?M zy=cMTfT}vjU4$yKdSAKTuT9QCQcl0C(PdRE&)zGTrl;Dy>wDp0!v;kZKwluUEy>8> zg!fV^xg=5LSkeBL>S&f$`s-09bv_$nejwl*a|&8w4xdaN_d1Sj8}%6k|6%JJp# z#k=bYB!{|dky3cAjZMTXF)3gtMCYRAGAqM^HL4-3oOB{iJMwE|3Sa+;h_%N4i>q@Z z&RM$26Zsa|R>HR~_gpoSh2My|G!e>yRwRl(Vm_IVqd zqdg^hvuI-JO{B}N5oe}lJ2Lg8QC;rhnhdX4@|tuz37{F4j{-Vlpa=WD0PP_N#9M%B z^BwpP7~8=A4P#rta;1#IbVeW`%JaobA>zSr-MJJvswP7gIFv3tq%eK$8~Bb8aqH3c zp&!DaSNB`TuO+20ZJ$$}!qFiYi!I(Cr7B_j_k;GP)o? zbMf-_bn)_F&HIvl4QFv|)0v-u0VDQkXodHQs7uk`CX>>|ZfBv;BZ*`EfbI9J8bcXC zKfT+jLkAF(7~(v?=efc()r#S85O5i9{BerkMf^}^)z@(bK*0A+uphI^#a1>6vv0Qt zri%Qe{8yI?=53Xny4?YchhY^-k1<$7+tnGu-EN+F5{%5GEKI`Xf|i{33C(q$hJfD< zz`EhpNm)lki60!4yV<@2Acg5pvYD^7%K|gs7yH^^p_8dKi+QY1X|H>ww)k_Vzc2u$ zXcKJ&u0mpd)}pP_@RP}_z)Ws1b}78jX61qZFNyY6462f#RbNu`Ii(XhU!&Uh0Urea z+`_S4ln&;k;n-##OJ|+hANptD-(HT|I$94pet5q`CuIjPZGu3iSaYL11LxoW4MjB= A00000 literal 0 HcmV?d00001 diff --git a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard index ee534a0..63a37c2 100644 --- a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard +++ b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard @@ -6,6 +6,7 @@ + @@ -18,39 +19,51 @@ + + + + - + - - - - + + + + + + + + - + @@ -72,31 +85,146 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -106,6 +234,8 @@ + + @@ -114,7 +244,12 @@ - + + + + + + diff --git a/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib b/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib index bdef7ce..b00e3f2 100644 --- a/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib +++ b/MobileInternshipTask/MobileInternshipTask/View/ReposCell/ReposCell.xib @@ -20,41 +20,31 @@ - - - - + - - + From fa7e3fc5d7c4a03908c74d6112d65689ccf28423 Mon Sep 17 00:00:00 2001 From: dawidramone Date: Wed, 2 May 2018 13:56:27 +0200 Subject: [PATCH 07/15] add UITextFieldDelegate and Override UITextField delegate method shouldChangeCharactersInRange --- .../Controller/ViewController.swift | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift index 0da840f..329e42a 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ViewController.swift @@ -8,7 +8,7 @@ import UIKit -class ViewController: UIViewController { +class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var userNameTxtFiled: UITextField! @IBOutlet weak var findUserOutlet: UIButton! @@ -19,6 +19,7 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + userNameTxtFiled.delegate = self checkConnectionToNetwork() addNavBarImage() } @@ -28,11 +29,19 @@ class ViewController: UIViewController { } override func prepare(for segue: UIStoryboardSegue, sender: Any? ) { - if segue.identifier == self.repoSegue { + if segue.identifier == repoSegue { let reposTableViewController = segue.destination as! ReposTableViewController reposTableViewController.repos = reposArray } } + + func textField(_ userNameTxtFiled: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + if string == " " { + return false + } else { + return true + } + } @IBAction func findUserButton(_ sender: Any) { searchForUser() @@ -75,7 +84,7 @@ class ViewController: UIViewController { } func loadActivityIndicator() { - activityIndicator.center = self.view.center + activityIndicator.center = view.center activityIndicator.hidesWhenStopped = true activityIndicator.activityIndicatorViewStyle = .whiteLarge view.addSubview(activityIndicator) @@ -101,13 +110,5 @@ class ViewController: UIViewController { } } - } - - - - - - - From 9207b49c4e5e5de7427295eb47b3661ac25cbe02 Mon Sep 17 00:00:00 2001 From: dawidramone Date: Wed, 2 May 2018 23:25:43 +0200 Subject: [PATCH 08/15] add convertDateToString() --- .../Controller/AppDelegate.swift | 13 +- .../Controller/ConnectedToNetwork.swift | 12 +- .../Controller/DetailRepoViewController.swift | 42 +++++-- .../Controller/ReposTableViewController.swift | 5 +- .../MobileInternshipTask/Model/Owner.swift | 28 ++--- .../Model/UserRepos.swift | 118 +++++++++--------- .../View/Base.lproj/Main.storyboard | 8 +- 7 files changed, 118 insertions(+), 108 deletions(-) diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift b/MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift index cb99ca9..3e77993 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/AppDelegate.swift @@ -15,30 +15,27 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. return true } func applicationWillResignActive(_ application: UIApplication) { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } func applicationDidEnterBackground(_ application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } func applicationWillEnterForeground(_ application: UIApplication) { - // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } func applicationDidBecomeActive(_ application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } func applicationWillTerminate(_ application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ConnectedToNetwork.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ConnectedToNetwork.swift index 9aa05d6..f9e7701 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ConnectedToNetwork.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ConnectedToNetwork.swift @@ -10,9 +10,8 @@ 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) @@ -28,19 +27,10 @@ public class Reachability { return false } - /* Only Working for WIFI - let isReachable = flags == .reachable - let needsConnection = flags == .connectionRequired - - return isReachable && !needsConnection - */ - - // Working for Cellular and WIFI 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/DetailRepoViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift index 7d4f065..be82179 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/DetailRepoViewController.swift @@ -18,9 +18,12 @@ class DetailRepoViewController: UIViewController { @IBOutlet weak var forksLabel: UILabel! var userRepo: UserRepos? + var dateCreated: String? + var dateUpdated: String? override func viewDidLoad() { super.viewDidLoad() + convertDateToString() roundedCorners() setupLabels() } @@ -28,18 +31,21 @@ class DetailRepoViewController: UIViewController { func setupLabels() { if let userRepos = userRepo { repoNameLabel.text = userRepos.name - descriptionLabel.text = userRepos.description - languageLabel.text = userRepos.language + 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\(dateUpdated ?? "-")" + createdLabel.text = "Created at: \n\(dateUpdated ?? "-")" } } @IBAction func seeDetailsButton(_ sender: Any) { - if let date = userRepo?.updated_at { - let dateFormatter = DateFormatter() - dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" - let datedate = dateFormatter.date(from: date) - print(datedate!) + if let htmlUrl = userRepo?.html_url { + guard let url = URL(string: htmlUrl) else {return} + UIApplication.shared.open(url, options: [:], completionHandler: nil ) } + } func roundedCorners() { @@ -59,4 +65,26 @@ class DetailRepoViewController: UIViewController { forksLabel.clipsToBounds = true } + 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) + dateUpdated = 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) + dateCreated = dateToString + } + } + } + } diff --git a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift index 3084323..4509607 100644 --- a/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift +++ b/MobileInternshipTask/MobileInternshipTask/Controller/ReposTableViewController.swift @@ -18,7 +18,7 @@ class ReposTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() userDoesntHaveRepos() - setUserNameInNav() + setUserPhotoInNav() registerCell() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { @@ -63,7 +63,7 @@ class ReposTableViewController: UITableViewController { } } - func setUserNameInNav() { + func setUserPhotoInNav() { if repos?.isEmpty == false { if let repos = repos { if let avatarUrl = repos[0].owner?.avatar_url { @@ -75,7 +75,6 @@ class ReposTableViewController: UITableViewController { if let dataImg = data { let image = UIImage(data: dataImg) DispatchQueue.main.async { - let image = image let imageView = UIImageView(image: image) imageView.contentMode = .scaleAspectFit self.navigationItem.titleView = imageView diff --git a/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift b/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift index a25bb97..a3e8544 100644 --- a/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift +++ b/MobileInternshipTask/MobileInternshipTask/Model/Owner.swift @@ -9,21 +9,21 @@ import Foundation struct Owner: Codable { - let login: String? - let id: Int? +// let login: String? +// let id: Int? let avatar_url: String? // let gravatar_id: String - let url: String? - let html_url: String? - let followers_url: String? - let following_url: String? - let gists_url: String? - let starred_url: String? - let subscriptions_url: String? - let organizations_url: String? - let repos_url: String? - let events_url: String? - let received_events_url: String? +// let url: String? +// let html_url: String? +// let followers_url: String? +// let following_url: String? +// let gists_url: String? +// let starred_url: String? +// let subscriptions_url: String? +// let organizations_url: String? +// let repos_url: String? +// let events_url: String? +// let received_events_url: String? // let type: String - let site_admin: Bool? +// let site_admin: Bool? } diff --git a/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift b/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift index ac551ef..8395243 100644 --- a/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift +++ b/MobileInternshipTask/MobileInternshipTask/Model/UserRepos.swift @@ -9,75 +9,71 @@ import Foundation struct UserRepos: Codable { - let id: Int? +// let id: Int? let name: String? - let full_name: String? +// let full_name: String? let owner: Owner? -// let private: String let html_url: String? let description: String? - let fork: Bool? - let url: String? - let forks_url: String? - let keys_url: String? - let collaborators_url: String? - let teams_url: String? - let hooks_url: String? - let issue_events_url: String? - let events_url: String? - let assignees_url: String? - let branches_url: String? - let tags_url: String? - let blobs_url: String? - let git_tags_url: String? - let git_refs_url: String? - let trees_url: String? - let statuses_url: String? - let languages_url: String? - let stargazers_url: String? - let contributors_url: String? - let subscribers_url: String? - let subscription_url: String? - let commits_url: String? - let git_commits_url: String? - let comments_url: String? - let issue_comment_url: String? - let contents_url: String? - let compare_url: String? - let merges_url: String? - let archive_url: String? - let downloads_url: String? - let issues_url: String? - let pulls_url: String? - let milestones_url: String? - let notifications_url: String? - let labels_url: String? - let releases_url: String? - let deployments_url: String? +// let fork: Bool? +// let url: String? +// let forks_url: String? +// let keys_url: String? +// let collaborators_url: String? +// let teams_url: String? +// let hooks_url: String? +// let issue_events_url: String? +// let events_url: String? +// let assignees_url: String? +// let branches_url: String? +// let tags_url: String? +// let blobs_url: String? +// let git_tags_url: String? +// let git_refs_url: String? +// let trees_url: String? +// let statuses_url: String? +// let languages_url: String? +// let stargazers_url: String? +// let contributors_url: String? +// let subscribers_url: String? +// let subscription_url: String? +// let commits_url: String? +// let git_commits_url: String? +// let comments_url: String? +// let issue_comment_url: String? +// let contents_url: String? +// let compare_url: String? +// let merges_url: String? +// let archive_url: String? +// let downloads_url: String? +// let issues_url: String? +// let pulls_url: String? +// let milestones_url: String? +// let notifications_url: String? +// let labels_url: String? +// let releases_url: String? +// let deployments_url: String? let created_at: String? let updated_at: String? - let pushed_at: String? - let git_url: String? - let ssh_url: String? - let clone_url: String? - let svn_url: String? -// let homepage: Homepage - let size: Int? - let stargazers_count: Int? +// let pushed_at: String? +// let git_url: String? +// let ssh_url: String? +// let clone_url: String? +// let svn_url: String? +// let size: Int? +// let stargazers_count: Int? let watchers_count: Int? let language: String? - let has_issues: Bool? - let has_projects: Bool? - let has_downloads: Bool? - let has_wiki: Bool? - let has_pages: Bool? - let forks_count: Int? -// let mirror_url: Mirror_url - let archived: Bool? - let open_issues_count: Int? -// let license: License +// let has_issues: Bool? +// let has_projects: Bool? +// let has_downloads: Bool? +// let has_wiki: Bool? +// let has_pages: Bool? +// let forks_count: Int? +// let archived: Bool? +// let open_issues_count: Int? let forks: Int? - let open_issues: Int? +// let open_issues: Int? let watchers: Int? - let default_branch: String? +// let default_branch: String? } diff --git a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard index 63a37c2..f51cf82 100644 --- a/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard +++ b/MobileInternshipTask/MobileInternshipTask/View/Base.lproj/Main.storyboard @@ -95,7 +95,7 @@ -