From 34cc49481564385095244cefb41539a1d47ecf48 Mon Sep 17 00:00:00 2001 From: Dmitrii Ivanov Date: Tue, 21 Jul 2020 12:29:54 +0200 Subject: [PATCH] initial --- AppStoreReviews.xcodeproj/project.pbxproj | 337 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../UserInterfaceState.xcuserstate | Bin 0 -> 28528 bytes .../xcschemes/xcschememanagement.plist | 14 + AppStoreReviews/AppDelegate.swift | 24 ++ .../AppIcon.appiconset/Contents.json | 98 +++++ AppStoreReviews/Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 ++ AppStoreReviews/DetailsViewController.swift | 79 ++++ AppStoreReviews/FeedViewController.swift | 50 +++ AppStoreReviews/Info.plist | 43 +++ AppStoreReviews/Review.swift | 26 ++ AppStoreReviews/ReviewCell.swift | 66 ++++ 14 files changed, 783 insertions(+) create mode 100644 AppStoreReviews.xcodeproj/project.pbxproj create mode 100644 AppStoreReviews.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 AppStoreReviews.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 AppStoreReviews.xcodeproj/project.xcworkspace/xcuserdata/un39nv.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 AppStoreReviews.xcodeproj/xcuserdata/un39nv.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 AppStoreReviews/AppDelegate.swift create mode 100644 AppStoreReviews/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 AppStoreReviews/Assets.xcassets/Contents.json create mode 100644 AppStoreReviews/Base.lproj/LaunchScreen.storyboard create mode 100644 AppStoreReviews/DetailsViewController.swift create mode 100644 AppStoreReviews/FeedViewController.swift create mode 100644 AppStoreReviews/Info.plist create mode 100644 AppStoreReviews/Review.swift create mode 100644 AppStoreReviews/ReviewCell.swift diff --git a/AppStoreReviews.xcodeproj/project.pbxproj b/AppStoreReviews.xcodeproj/project.pbxproj new file mode 100644 index 0000000..b8355af --- /dev/null +++ b/AppStoreReviews.xcodeproj/project.pbxproj @@ -0,0 +1,337 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 345AD11C24C6EDD9004E2EE1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345AD11B24C6EDD9004E2EE1 /* AppDelegate.swift */; }; + 345AD12524C6EDDC004E2EE1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 345AD12424C6EDDC004E2EE1 /* Assets.xcassets */; }; + 345AD12824C6EDDC004E2EE1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 345AD12624C6EDDC004E2EE1 /* LaunchScreen.storyboard */; }; + 345AD13324C6EE64004E2EE1 /* FeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345AD12F24C6EE64004E2EE1 /* FeedViewController.swift */; }; + 345AD13424C6EE64004E2EE1 /* ReviewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345AD13024C6EE64004E2EE1 /* ReviewCell.swift */; }; + 345AD13524C6EE64004E2EE1 /* Review.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345AD13124C6EE64004E2EE1 /* Review.swift */; }; + 345AD13624C6EE64004E2EE1 /* DetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345AD13224C6EE64004E2EE1 /* DetailsViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 345AD11824C6EDD9004E2EE1 /* AppStoreReviews.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppStoreReviews.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 345AD11B24C6EDD9004E2EE1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 345AD12424C6EDDC004E2EE1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 345AD12724C6EDDC004E2EE1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 345AD12924C6EDDC004E2EE1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 345AD12F24C6EE64004E2EE1 /* FeedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedViewController.swift; sourceTree = ""; }; + 345AD13024C6EE64004E2EE1 /* ReviewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReviewCell.swift; sourceTree = ""; }; + 345AD13124C6EE64004E2EE1 /* Review.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Review.swift; sourceTree = ""; }; + 345AD13224C6EE64004E2EE1 /* DetailsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailsViewController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 345AD11524C6EDD9004E2EE1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 345AD10F24C6EDD9004E2EE1 = { + isa = PBXGroup; + children = ( + 345AD11A24C6EDD9004E2EE1 /* AppStoreReviews */, + 345AD11924C6EDD9004E2EE1 /* Products */, + ); + sourceTree = ""; + }; + 345AD11924C6EDD9004E2EE1 /* Products */ = { + isa = PBXGroup; + children = ( + 345AD11824C6EDD9004E2EE1 /* AppStoreReviews.app */, + ); + name = Products; + sourceTree = ""; + }; + 345AD11A24C6EDD9004E2EE1 /* AppStoreReviews */ = { + isa = PBXGroup; + children = ( + 345AD13224C6EE64004E2EE1 /* DetailsViewController.swift */, + 345AD12F24C6EE64004E2EE1 /* FeedViewController.swift */, + 345AD13124C6EE64004E2EE1 /* Review.swift */, + 345AD13024C6EE64004E2EE1 /* ReviewCell.swift */, + 345AD11B24C6EDD9004E2EE1 /* AppDelegate.swift */, + 345AD12424C6EDDC004E2EE1 /* Assets.xcassets */, + 345AD12624C6EDDC004E2EE1 /* LaunchScreen.storyboard */, + 345AD12924C6EDDC004E2EE1 /* Info.plist */, + ); + path = AppStoreReviews; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 345AD11724C6EDD9004E2EE1 /* AppStoreReviews */ = { + isa = PBXNativeTarget; + buildConfigurationList = 345AD12C24C6EDDC004E2EE1 /* Build configuration list for PBXNativeTarget "AppStoreReviews" */; + buildPhases = ( + 345AD11424C6EDD9004E2EE1 /* Sources */, + 345AD11524C6EDD9004E2EE1 /* Frameworks */, + 345AD11624C6EDD9004E2EE1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppStoreReviews; + productName = AppStoreReviews; + productReference = 345AD11824C6EDD9004E2EE1 /* AppStoreReviews.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 345AD11024C6EDD9004E2EE1 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1160; + LastUpgradeCheck = 1160; + ORGANIZATIONNAME = ING; + TargetAttributes = { + 345AD11724C6EDD9004E2EE1 = { + CreatedOnToolsVersion = 11.6; + }; + }; + }; + buildConfigurationList = 345AD11324C6EDD9004E2EE1 /* Build configuration list for PBXProject "AppStoreReviews" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 345AD10F24C6EDD9004E2EE1; + productRefGroup = 345AD11924C6EDD9004E2EE1 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 345AD11724C6EDD9004E2EE1 /* AppStoreReviews */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 345AD11624C6EDD9004E2EE1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 345AD12824C6EDDC004E2EE1 /* LaunchScreen.storyboard in Resources */, + 345AD12524C6EDDC004E2EE1 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 345AD11424C6EDD9004E2EE1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 345AD13524C6EE64004E2EE1 /* Review.swift in Sources */, + 345AD13424C6EE64004E2EE1 /* ReviewCell.swift in Sources */, + 345AD13324C6EE64004E2EE1 /* FeedViewController.swift in Sources */, + 345AD11C24C6EDD9004E2EE1 /* AppDelegate.swift in Sources */, + 345AD13624C6EE64004E2EE1 /* DetailsViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 345AD12624C6EDDC004E2EE1 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 345AD12724C6EDDC004E2EE1 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 345AD12A24C6EDDC004E2EE1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.6; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 345AD12B24C6EDDC004E2EE1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.6; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 345AD12D24C6EDDC004E2EE1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AppStoreReviews/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.ing.AppStoreReviews; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 345AD12E24C6EDDC004E2EE1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AppStoreReviews/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.ing.AppStoreReviews; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 345AD11324C6EDD9004E2EE1 /* Build configuration list for PBXProject "AppStoreReviews" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 345AD12A24C6EDDC004E2EE1 /* Debug */, + 345AD12B24C6EDDC004E2EE1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 345AD12C24C6EDDC004E2EE1 /* Build configuration list for PBXNativeTarget "AppStoreReviews" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 345AD12D24C6EDDC004E2EE1 /* Debug */, + 345AD12E24C6EDDC004E2EE1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 345AD11024C6EDD9004E2EE1 /* Project object */; +} diff --git a/AppStoreReviews.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/AppStoreReviews.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..967a192 --- /dev/null +++ b/AppStoreReviews.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/AppStoreReviews.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/AppStoreReviews.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/AppStoreReviews.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/AppStoreReviews.xcodeproj/project.xcworkspace/xcuserdata/un39nv.xcuserdatad/UserInterfaceState.xcuserstate b/AppStoreReviews.xcodeproj/project.xcworkspace/xcuserdata/un39nv.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..cf7e105846719fbce2b07ab245c6a0763a0b6e25 GIT binary patch literal 28528 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 literal 0 HcmV?d00001 diff --git a/AppStoreReviews.xcodeproj/xcuserdata/un39nv.xcuserdatad/xcschemes/xcschememanagement.plist b/AppStoreReviews.xcodeproj/xcuserdata/un39nv.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..98f21b6 --- /dev/null +++ b/AppStoreReviews.xcodeproj/xcuserdata/un39nv.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + AppStoreReviews.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/AppStoreReviews/AppDelegate.swift b/AppStoreReviews/AppDelegate.swift new file mode 100644 index 0000000..426c7ec --- /dev/null +++ b/AppStoreReviews/AppDelegate.swift @@ -0,0 +1,24 @@ +// +// AppDelegate.swift +// AppStoreReviews +// +// Created by Dmitrii Ivanov on 21/07/2020. +// Copyright © 2020 ING. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + window = UIWindow(frame: UIScreen.main.bounds) + let viewController = FeedViewController() + window?.rootViewController = UINavigationController(rootViewController: viewController) + window?.makeKeyAndVisible() + return true + } +} + diff --git a/AppStoreReviews/Assets.xcassets/AppIcon.appiconset/Contents.json b/AppStoreReviews/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/AppStoreReviews/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AppStoreReviews/Assets.xcassets/Contents.json b/AppStoreReviews/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/AppStoreReviews/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AppStoreReviews/Base.lproj/LaunchScreen.storyboard b/AppStoreReviews/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/AppStoreReviews/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AppStoreReviews/DetailsViewController.swift b/AppStoreReviews/DetailsViewController.swift new file mode 100644 index 0000000..800a7d1 --- /dev/null +++ b/AppStoreReviews/DetailsViewController.swift @@ -0,0 +1,79 @@ +// +// AppDelegate.swift +// AppStoreReviews +// +// Created by Dmitrii Ivanov on 21/07/2020. +// Copyright © 2020 ING. All rights reserved. +// + +import UIKit + +class DetailsViewController: UIViewController { + + private let review: Review + + private var titleLabel = UILabel() + private var authorLabel = UILabel() + private var contentLabel = UILabel() + private var ratingVersionLabel = UILabel() + + init(review: Review) { + self.review = review + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = UIColor.white + setupViews() + } + + func setupViews() { + titleLabel.translatesAutoresizingMaskIntoConstraints = false + authorLabel.translatesAutoresizingMaskIntoConstraints = false + contentLabel.translatesAutoresizingMaskIntoConstraints = false + ratingVersionLabel.translatesAutoresizingMaskIntoConstraints = false + + view.addSubview(ratingVersionLabel) + view.addSubview(authorLabel) + view.addSubview(titleLabel) + view.addSubview(contentLabel) + + ratingVersionLabel.text = review.ratingVersionText() + ratingVersionLabel.font = UIFont.italicSystemFont(ofSize: 18) + + authorLabel.text = review.author + authorLabel.font = UIFont.systemFont(ofSize: 18) + + titleLabel.text = review.title + titleLabel.numberOfLines = 0 + titleLabel.font = UIFont.boldSystemFont(ofSize: 22) + + contentLabel.text = review.content + contentLabel.numberOfLines = 0 + + ratingVersionLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8).isActive = true + ratingVersionLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8).isActive = true + ratingVersionLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8).isActive = true + ratingVersionLabel.heightAnchor.constraint(equalToConstant: 24).isActive = true + + authorLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8).isActive = true + authorLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8).isActive = true + authorLabel.topAnchor.constraint(equalTo: ratingVersionLabel.bottomAnchor, constant: 8).isActive = true + authorLabel.heightAnchor.constraint(equalToConstant: 24).isActive = true + + titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8).isActive = true + titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8).isActive = true + titleLabel.topAnchor.constraint(equalTo: authorLabel.bottomAnchor, constant: 8).isActive = true + titleLabel.heightAnchor.constraint(lessThanOrEqualToConstant: 72).isActive = true + + contentLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8).isActive = true + contentLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8).isActive = true + contentLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8).isActive = true + contentLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 24).isActive = true + } +} diff --git a/AppStoreReviews/FeedViewController.swift b/AppStoreReviews/FeedViewController.swift new file mode 100644 index 0000000..ccbc496 --- /dev/null +++ b/AppStoreReviews/FeedViewController.swift @@ -0,0 +1,50 @@ +// +// AppDelegate.swift +// AppStoreReviews +// +// Created by Dmitrii Ivanov on 21/07/2020. +// Copyright © 2020 ING. All rights reserved. +// + +import UIKit + +class FeedViewController: UITableViewController { + + override func viewDidLoad() { + super.viewDidLoad() + tableView.register(ReviewCell.self, forCellReuseIdentifier: "cellId") + tableView.rowHeight = 160 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 100 + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let c = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! ReviewCell + c.update(item: randomReview()) + return c + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + let vc = DetailsViewController(review: randomReview()) + navigationController!.pushViewController(vc, animated: true) + } + + func randomReview() -> Review { + let author = ["Dan Auerbach", "Bo Diddley", "Otis Rush", "Jimi Hendrix", "Albert King", "Buddy Guy", "Muddy Waters", "Eric Clapton"].randomElement()! + let version = ["3.11", "3.12"].randomElement()! + let rating = Int.random(in: 1...5) + let title = ["Awesome app", "Could be better", "Gimme my money back!!", "Lemme tell you a story..."].randomElement()! + let id = UUID().uuidString + let content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + return Review(author: author, + version: version, + rating: rating, + title: title, + id: id, + content: content) + } +} + diff --git a/AppStoreReviews/Info.plist b/AppStoreReviews/Info.plist new file mode 100644 index 0000000..5a63475 --- /dev/null +++ b/AppStoreReviews/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/AppStoreReviews/Review.swift b/AppStoreReviews/Review.swift new file mode 100644 index 0000000..d83086c --- /dev/null +++ b/AppStoreReviews/Review.swift @@ -0,0 +1,26 @@ +// +// AppDelegate.swift +// AppStoreReviews +// +// Created by Dmitrii Ivanov on 21/07/2020. +// Copyright © 2020 ING. All rights reserved. +// + +import Foundation + +struct Review { + let author: String + let version: String + let rating: Int + let title: String + let id: String + let content: String + + func ratingVersionText() -> String { + var stars = "" + for _ in 0..