Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task is done #1

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
UserInterfaceState.xcuserstate
TakeHomeApp.xcworkspace/contents.xcworkspacedata
TakeHomeApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
Pods/*
Breakpoints_v2.xcbkptlist
23 changes: 23 additions & 0 deletions Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'TakeHomeApp' do

use_frameworks!
pod 'Alamofire', '~> 5.5'
pod 'AlamofireImage', '~> 4.1'
pod 'SnapKit', '~> 5.0.0'
pod 'ReachabilitySwift', '3'
pod 'SVProgressHUD', '2.2.5'
pod 'Toast-Swift', '5.0.1'

target 'TakeHomeAppTests' do
inherit! :search_paths
# Pods for testing
end

target 'TakeHomeAppUITests' do
# Pods for testing
end

end
306 changes: 300 additions & 6 deletions TakeHomeApp.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion TakeHomeApp/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = ViewController()
let navigationController = UINavigationController(rootViewController: PlacesListVC())
window.rootViewController = navigationController
window.makeKeyAndVisible()

self.window = window
Expand Down
30 changes: 25 additions & 5 deletions TakeHomeApp/Base.lproj/LaunchScreen.storyboard
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
Expand All @@ -11,15 +14,32 @@
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Welcome to Storm ideas Challenge" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XgK-Pd-GUK">
<rect key="frame" x="74" y="443" width="266" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="XgK-Pd-GUK" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="Wsh-Oc-9RU"/>
<constraint firstItem="XgK-Pd-GUK" firstAttribute="centerY" secondItem="6Tk-OE-BBY" secondAttribute="centerY" id="tvP-KS-hYh"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
7 changes: 7 additions & 0 deletions TakeHomeApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
Expand Down
19 changes: 19 additions & 0 deletions TakeHomeApp/Models/Place.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Place.swift
// TakeHomeApp
//
// Created by Hesham Donia on 28/03/2022.
//

import Foundation

struct PlacesResponse: Codable {
var places: [Place]?
}

struct Place: Codable {
var id: String?
var createdAt: String?
var name: String?
var thumbnail: String?
}
19 changes: 19 additions & 0 deletions TakeHomeApp/Models/PlacePhoto.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// PlacePhoto.swift
// TakeHomeApp
//
// Created by Hesham Donia on 28/03/2022.
//

import Foundation

struct PlacePhotosResponse: Codable {
var placePhotos: [PlacePhoto]?
}

struct PlacePhoto: Codable {
var id: String?
var createdAt: String?
var placeId: String?
var image: String?
}
33 changes: 33 additions & 0 deletions TakeHomeApp/Models/StatusServer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// StatusServer.swift
// TakeHomeApp
//
// Created by Hesham Donia on 28/03/2022.
//

import Foundation

class StatusServer: Codable {
var statusCode: Int?
var message: String?
var errors: [APIError]?

enum CodingKeys: String, CodingKey {
case statusCode = "status"
case message, errors
}

init(message: String) {
self.message = message
}
}

class APIError: Codable {
var statusCode: Int?
var message: String?

enum CodingKeys: String, CodingKey {
case statusCode = "code"
case message
}
}
25 changes: 25 additions & 0 deletions TakeHomeApp/PlacePhotos/Cells/PlacePhotoCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// PlacePhotoCell.swift
// TakeHomeApp
//
// Created by Hesham Donia on 28/03/2022.
//

import UIKit

class PlacePhotoCell: UICollectionViewCell {
public static let identifier = "PlacePhotoCell"
var view: PlacePhotoCellView?

func configureCell(image: String?) {
view = PlacePhotoCellView(view: contentView)
view?.configureViews()
view?.showData(image: image)
}

override func prepareForReuse() {
super.prepareForReuse()
view?.resetViews()
}

}
54 changes: 54 additions & 0 deletions TakeHomeApp/PlacePhotos/Cells/PlacePhotoCellView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// PlacePhotoCellView.swift
// TakeHomeApp
//
// Created by Hesham Donia on 28/03/2022.
//

import SnapKit
import Alamofire
import AlamofireImage

class PlacePhotoCellView: BaseView {

lazy var placePhotoImageView: UIImageView = {
var imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
return imageView
}()

override init(view: UIView) {
super.init(view: view)
}

func configureViews() {
containerView.addSubViews(subViews: [placePhotoImageView])

placePhotoImageView.snp.makeConstraints { [weak self] make in
guard let self = self else {return}
make.leading.top.equalTo(self.containerView)
make.trailing.bottom.equalTo(self.containerView)
}
}

func showData(image: String?) {
if let placeImage = image, let url = URL(string: placeImage) {
if ImagesCachingManager.isImageCached(imageUrl: placeImage) {
placePhotoImageView.image = ImagesCachingManager.getImage(imageUrl: placeImage)
} else {
AF.request(url).responseImage { [weak self] response in
guard let self = self else {return}
if case .success(let image) = response.result {
self.placePhotoImageView.image = image
ImagesCachingManager.addToCache(imageUrl: placeImage, image: image)
}
}
}

}
}

func resetViews() {
placePhotoImageView.image = nil
}
}
58 changes: 58 additions & 0 deletions TakeHomeApp/PlacePhotos/PlacePhotosVC.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// PlacePhotosVC.swift
// TakeHomeApp
//
// Created by Hesham Donia on 28/03/2022.
//

import UIKit

class PlacePhotosVC: UIViewController {

var placeId: String!
var placeName: String!

var placePhotosView: PlacePhotosView!
var viewModel: PlacesViewModel? = PlacesViewModelImpl()

override func viewDidLoad() {
super.viewDidLoad()
self.title = placeName
placePhotosView = PlacePhotosView(view: view, dataSource: self, delegate: self)
placePhotosView.configureViews()

viewModel?.placePhotos?.bind({ [weak self] _ in
self?.placePhotosView.placePhotosCollectionView.reloadData()
})
viewModel?.loading?.bind({ [weak self] isLoading in
if isLoading {
self?.placePhotosView.showLoader()
} else {
self?.placePhotosView.hideLoader()
}
})
viewModel?.error?.bind({ [weak self] errorMessage in
self?.placePhotosView.showErrorMessage(message: errorMessage)
})
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
viewModel?.getPlacePhotos(placeId: placeId)
}

}

extension PlacePhotosVC: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return viewModel?.placePhotos?.value.count ?? 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PlacePhotoCell.identifier, for: indexPath) as? PlacePhotoCell {
cell.configureCell(image: viewModel?.placePhotos?.value[indexPath.row].image)
return cell
}
return UICollectionViewCell()
}
}
38 changes: 38 additions & 0 deletions TakeHomeApp/PlacePhotos/PlacePhotosView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// PlacePhotosView.swift
// TakeHomeApp
//
// Created by Hesham Donia on 28/03/2022.
//

import SnapKit

class PlacePhotosView: BaseView {
lazy var placePhotosCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)

var collectionView = UICollectionView(frame: UIScreen.main.bounds, collectionViewLayout: layout)
collectionView.register(PlacePhotoCell.self, forCellWithReuseIdentifier: PlacePhotoCell.identifier)
collectionView.contentInsetAdjustmentBehavior = .never
return collectionView
}()

init(view: UIView, dataSource: UICollectionViewDataSource, delegate: UICollectionViewDelegate) {
super.init(view: view)
placePhotosCollectionView.dataSource = dataSource
placePhotosCollectionView.delegate = delegate
placePhotosCollectionView.isPagingEnabled = true
}

func configureViews() {
containerView.addSubViews(subViews: [placePhotosCollectionView])

placePhotosCollectionView.snp.makeConstraints { [weak self] make in
guard let self = self else {return}
make.leading.top.equalTo(self.containerView)
make.bottom.trailing.equalTo(self.containerView)
}
}
}
25 changes: 25 additions & 0 deletions TakeHomeApp/PlacesList/Cells/PlaceCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// PlaceCell.swift
// TakeHomeApp
//
// Created by Hesham Donia on 28/03/2022.
//

import UIKit

class PlaceCell: UITableViewCell {

public static let identifier = "PlaceCell"
var view: PlaceCellView?

func configureCell(place: Place?) {
view = PlaceCellView(view: contentView)
view?.configureViews()
view?.showData(place: place)
}

override func prepareForReuse() {
super.prepareForReuse()
view?.resetViews()
}
}
Loading