Skip to content

pahmed/TheArabianCenter

 
 

Repository files navigation

The Arabian Center

Dependency manager

CocoaPods

Architecture

Following Clean Swift based on Uncle bob Clean Architecture

The Main Life Cycle based on 3 letters VIP VIP

Relation between components

  1. The view controller’s output connects to the interactor’s input.
  2. The interactor’s output connects to the presenter’s input.
  3. The presenter’s output connects to the view controller’s input.

We’ll create special objects to pass data through the boundaries between the components. This allows us to decouple the underlying data models from the components. These special objects consists of only primitive types such as Int, Double, and String. We can create structs, classes, or enums to represent the data but there should only be primitive types inside these containing entities.

A typical scenario goes like.

  1. The user taps a button in the app’s user interface.
  2. The tap gesture comes in through the IBActions in the view controller.
  3. The view controller constructs a request object and sends it to the interactor.
  4. The interactor takes the request object and performs some work. It then puts the results in a response object and sends it to the presenter.
  5. The presenter takes the response object and formats the results. It then puts the formatted result in a view model object and sends it back to the view controller.
  6. Finally, the view controller displays the results to the user.

Responsibility for each component

  1. View Controller Handle user interface that the user can interact with, also collects the user inputs.
  2. Interactor Contains the app’s business logic.
  3. Worker Handle data that may be stored in Core Data or over the network. (Long time or background process).
  4. Presenter Prepare the data to be view in simplest way or in primitive data type (String,UIImage,...etc). For Example: Localization, formatting (Date,Currency,Time,...etc)
  5. Router prepare the data to be transferred to new view controller by deliver it from the interactor (view controller output) in current view controller to the interactor (view controller output) for new view controller.

Error Handling

Asynchronous error handling for Workers (Result pattern)

func downloadImage(imageRequest:Image.Download.Request,compilation:@escaping (Result<Image.Download.Response,Image.Download.Error>)->()) {

        ImageDownloader.default.downloadImage(with: imageRequest.url, completionHandler: { (image, error, cachType, url) in

            guard let image :UIImage = image else{
                compilation(.failure(Image.Download.Error.failDuringDownload))
                return
            }

            let respose = Image.Download.Response(image: image)
            compilation(.success(respose))
        })

We have a enum with 2 cases, one for success with associated type, and one for failure with associated error type

And can be used as following

let syncWorker = SyncWorker()

       syncWorker.downloadImage(imageRequest: Image.Download.Request(url: imageURL), compilation: { (result) in
           switch result{
           case let .success(response):
               self.output.presentRetrieveImageSucceed(response:response)
           case let .failure(error):
               self.output.presentRetrieveImageError(error: UI.Image.Download.Error.failure(error: error))
           }
       })

Using a switch statement allows powerful pattern matching, and ensures all possible results are covered

Libraries

RxSwift is a Swift version of Rx, It is a combination of the Observer pattern, the Iterator pattern, and functional programming.

It is to enable easy composition of asynchronous operations and event/data streams, KVO observing, async operations and streams are all unified under abstraction of sequence. This is the reason why Rx is so simple, elegant and powerful.

for more info: ReactiveX

RxSwift extensions for UI, NSURLSession, KVO ...

It is an iOS drop-in class that displays a translucent HUD with an indicator and/or labels while work is being done in a background thread.

It is a framework written in Swift that makes it easy for you to convert your model objects (classes and structs) to and from JSON.

Result<Value, Error> values are either successful (wrapping Value) or failed (wrapping Error). This is similar to Swift’s native Optional type: success is like some, and failure is like none except with an associated Error value. The addition of an associated Error allows errors to be passed along for logging or displaying to the user.

It is a Swift framework for intelligently requesting permissions from users. It contains not only a simple UI to request permissions but also a unified permissions API that can tell you the status of any given system permission or easily request them.

It provides an elegant way to navigate through view controllers by URLs.

It is a lightweight, pure-Swift library for downloading and caching images from the web.

Development and Release notes

  1. Localization: Apple recommend to restart the iOS app, but this is not what developers and business team prefer so I make something to load the localization of the app in runtime without restarting. To make every thing in the app localized perfectly you should restarting the app.(UIImagePickerController, Permissions Popup)

  2. Deep Linking [Ref] I’m working with URI scheme for Deeplinking not Associated Domains(iOS 9+) because I don’t have a personal iOS Apple Developer membership for now.

  3. In order to use a URI scheme, I have to manually handle the case of the app not being installed. The typical process was to attempt to open up the app in Javascript by setting window.location to the URI path that you wanted. (Twitter Only)

  4. 2 Unit Tests and 1 UI test cases added as samples

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 96.9%
  • Objective-C 1.8%
  • Ruby 1.2%
  • C 0.1%