CI Example Project

Related tags

Networking BookStore
Overview

BookStore

๐Ÿ‘‰ ํ•œ๊ธ€ ๋ฒ„์ „

See new releases and search for programming books from IT Bookstore API

This is a sample app to practice using Result type, stubbing network request for unit tests, separating functionalities into frameworks, and writing Swift documentation.

How to run

> cd BookStore
> open BookStore.xcodeproj

Run!

Contents

App Features

What's New

A simple UITableView with cells and modal presentation for a detailed page.

Search

  1. As a user types in the keyword, the search text is "debounced" for a fraction of second for better performance and user experience. See Debouncer.

  2. Search results are paginated and provides infinite scroll.

Result type in Swift 5

Out of the box, you have to switch on the Result instance to access the underlying success instance or the error instance.

switch result {
case .success(let response):
  //do something with the response
case .failure(let error):
  //handle error
}

However, I think switch statements are too wordy. I added success and catch method to Result type. So it can be chained like this.

searchResult.success { response in
  //do something with the response
}.catch { error in
  //handle error
}

Even cleaner, like this.

result.success(handleSuccess)
      .catch(handleError)
      
func handleSuccess(_ result: SearchResult) { ... }
func handleError(_ error: Error) { ... }

Stubbing Network Requests for Unit Tests

Generally, it is not a good idea to rely on the actual network requests for unit tests because it adds too much dependency on tests. One way to stub networking is to subclass URLProtocol.

1. Subclass URLProtocol

See MockURLProtocol

2. Configure URLSession with your mock URLProtocol

let config = URLSessionConfiguration.ephemeral
config.protocolClasses = [MockURLProtocol.self]

//Use this URLSession instance to make requests.
let session = URLSession(configuration: config) 

4. Use the configured URLSession instance just as you would.

session.dataTask(with: urlRequest) { (data, response, error) in
  //Stubbed response
}.resume()

UI Testing with Stubbed Network Data

The above method(as well as the famous OHHTTPStubs) doesn't work for UI testing because the test bundle and the app bundle (XCUIApplication) are loaded in separate processes. By using Swifter, you can run a local http server on the simulator.

First, change the API endpoints during UI testing with launchArguments in your hosting app.

//In XCTestCase,
override func setUp() {
  app = XCUIApplication()
  app.launchArguments = ["-uitesting"]
}

//In AppDelegate's application(_:didFinishLaunchingWithOptions:)
if ProcessInfo.processInfo.arguments.contains("-uitesting") {
  BookStoreConfiguration.shared.setBaseURL(URL(string: "http://localhost:8080")!)
}

Then stub the network and test the UI with it.

let server = HttpServer()

func testNewBooksNormal() {
  do {
    let path = try TestUtil.path(for: normalResponseJSONFilename, in: type(of: self))
    server[newBooksPath] = shareFile(path)
    try server.start()
    app.launch()
  } catch {
    XCTAssert(false, "Swifter Server failed to start.")
  }
        
  XCTContext.runActivity(named: "Test Successful TableView Screen") { _ in
    XCTAssert(app.tables[tableViewIdentifier].waitForExistence(timeout: 3))
    XCTAssert(app.tables[tableViewIdentifier].cells.count > 0)
    XCTAssert(app.staticTexts["9781788476249"].exists)
    XCTAssert(app.staticTexts["$44.99"].exists)
  }
}

Using Frameworks for independent functionalities

Separating your app's functions into targets has several advantages. It forces you to care about dependencies, and it is good for unit tests since features are sandboxed. However, it may slow down the app launch (by little) due to framework loading.

BookStoreKit is responsible for fetching and searching books data from IT Bookstore API.

Networking is a wrapper around URLSession for making HTTP requests and parsing response.

Writing a documentation comment

Swift's API Design Guidelines suggest you write a documentation comment for every declaration. Writing one can have an impact on the design.

1. Write

Reference this document for markup formatting.

2. Check out the result

In Xcode's autocompletion

and Show Quick Help (option + click)

Getting Rid of IUOs

IMHO Implictly unwrapped optional is a potential threat to code safety and should be avoided as much as possible if not altogether. An example of two methods to get rid of them from where they are commonly used.

Make IBOutlets Optional

IBOutlets are IUOs by Apple's default. However, you can change that to Optional types. You may worry that making IBOutlets Optionals may cause too many if lets or guards, but that concern may just be overrated. IBOutlets are mostly used to set values on them, so optional chaining is sufficient. In just few cases where unwrapping is added, I will embrace them for additional safety of my code.

Using lazy instantiation

For the properties of UIViewController subclass, IUO can be useful but it's still dangerous. Instead, I use unspecified. It generates a crash upon class/struct usage so it can be spotted fast during development, and most importantly no more IUOs.

//Inside a viewcontroller
lazy var bookStore: BookStoreService = unspecified()
You might also like...
Demo project to try WebRTC native bindings in .net MAUI

MAUI.WebRTC.Demo Demo project to try WebRTC native bindings in .net MAUI. There are two projects with Xamarin bindings https://github.com/melihercan/W

NintendoSwitch-BezierPath-Example - Nintendo Switch Bezier Path Example

NintendoSwitch-BezierPath-Example An example app that demonstrates the use of Be

Assignment 2 - A fully functional example in the CardinalKit-Example directory
Assignment 2 - A fully functional example in the CardinalKit-Example directory

Assignment 2 - A fully functional example in the CardinalKit-Example directory

This is an example project of SwiftUI and Combine using GitHub API.
This is an example project of SwiftUI and Combine using GitHub API.

SwiftUI-Combine-Example This is an example project of SwiftUI and Combine using GitHub GET /search/users API. ๐Ÿ“‹ Requirements Swift5.1 Beta Xcode11.0

AsyncImageExample An example project for AsyncImage. Loading images in SwiftUI article.
AsyncImageExample An example project for AsyncImage. Loading images in SwiftUI article.

AsyncImageExample An example project for AsyncImage. Loading images in SwiftUI article. Note: The project works in Xcode 13.0 beta (13A5154h).

An example project of using the new Character Controller component in RealityKit 2.0
An example project of using the new Character Controller component in RealityKit 2.0

CharacterController in RealityKit 2.0 An example project of using the new Character Controller component in RealityKit 2.0. Demo Tweet Usage Install a

An example project to demonstrate the new scripting capabilities of Shortcuts For Mac.
An example project to demonstrate the new scripting capabilities of Shortcuts For Mac.

Scripting Shortcuts Test Project This simple project is designed to test the new scripting capabilities introduced in the Shortcuts app in macOS Monte

Example project guide you schedules multiple thread for network requests in RxSwift, which is optimize your app's performance better.
Example project guide you schedules multiple thread for network requests in RxSwift, which is optimize your app's performance better.

RxSwift-Multi-Threading-Example Example project guide you schedules multiple thread for network requests in RxSwift, which is optimize your app's perf

This is example project for my presentation in iOSDC JAPAN 2021

Swift PM Project Example This is example project for my presentation in iOSDC JAPAN 2021. Package.swift based project management Multi Modules Multi P

Example Xcode swift iOS project for Core Data + iCloud syncing
Example Xcode swift iOS project for Core Data + iCloud syncing

iCloudCoreDataStarter Hello, I'm Chad. For the last several months I have been working on Sticker Doodle, an app you should go download right now! In

CI Example Project
CI Example Project

BookStore ๐Ÿ‘‰ ํ•œ๊ธ€ ๋ฒ„์ „ See new releases and search for programming books from IT Bookstore API This is a sample app to practice using Result type, stubbin

An example project showing how to use `overrideUserInterfaceStyle` to build an in-app light/dark mode switch

OverrideDarkMode A sample project to show how using overrideUserInterfaceStyle enables having a dark / light mode switch directly in the app, while st

Grpc example project for swift

How to gRPC on Swift Projects This file aims to guide you to gRPC implementation on your swift project. Installing the Protobuf Compiler Open Terminal

An example project showing how to extract and color anchor geometry in RealityKit
An example project showing how to extract and color anchor geometry in RealityKit

RealityKit - Extracting anchor geometry to create a custom Mesh An example project showing how to extract anchor geometry from ARMeshAnchor, create a

Example project showing how to use async/await with iOS 13
Example project showing how to use async/await with iOS 13

ios13AsyncAwait Example project showing how to use async/await with iOS 13 Article This source code is a part of an article published at This Dev Brai

Example project which uses Machine Learning frameworks to detect things

ML_IOS Example project which uses Machine Learning frameworks to detect things. Features Object Detection Text Detection Face Detection Audio Detectio

This is swift project example to connect VNPTSmartCA SDK using Swift Language.

Example source code to integrate with VNPTSmartCA iOS SDK To run the example project, clone repository, and run pod install Requirements Installation

ProductPage - An example project that shows how to build a product page in a modular way. SwiftUI practice

ProductPage An example project that shows how to build a product page in a modul

This is an example project of SwiftUI and Combine using GitHub API.
This is an example project of SwiftUI and Combine using GitHub API.

SwiftUI-Combine-Example This is an example project of SwiftUI and Combine using GitHub GET /search/users API. ๐Ÿ“‹ Requirements Swift5.1 Beta Xcode11.0

Owner
Danny Gilbert
iOS / DevOps Engineer and lover of all things Swift.
Danny Gilbert
Klab Academy, example of calling APIs in flutter

klab A new Flutter application. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this

Hubert IT 0 Dec 2, 2021
Layer + Parse iOS Example (Swift)

Note: I no longer actively working on this project. If you encounter any problem, please open an issue and hopefully the community will help out. If y

Kien 119 Feb 10, 2022
MVVM project to show AQI of cities via web socket

Air Quality Monitoring Application Swift project with JSON parsing using codable About the application The app consists of live realtime data from the

Pran Kishore 0 Nov 27, 2021
iOS Project Manager Client

08-iOS-Project-Manager-Client ํ”„๋กœ์ ํŠธ ๋งค๋‹ˆ์ € STEP 1 ํ”„๋กœ์ ํŠธ ํ• ์ผ ๋ฆฌ์ŠคํŠธ ๊ธฐ๋Šฅ๊ตฌํ˜„ UI๊ตฌํ˜„๋ฐฉ์‹ : ์ฝ”๋“œ ์•„ํ‚คํ…์ณ : ProjectManagerViewController : NavigationViewController์œ„์— StackView(

Kioding87 1 Nov 19, 2021
Little project I wrote a while ago I decided to clean up and upload.

ImageSearch About The project uses the Pixabay (https://pixabay.com/) API to show images relating to entered text. The app is built using an MVVM arch

Jay Bennett 0 Dec 7, 2021
ADVANCED APP DESIGN The main goal of this mini project is to inspire you on what we can accomplish with the SwiftUI framework.

Restart-App.0.2 ADVANCED APP DESIGN The main goal of this mini project is to inspire you on what we can accomplish with the SwiftUI framework. COMPLEX

Noye Samuel 1 Dec 11, 2021
EasyImplementationAlamoFire - An iOS project to demonstrate the usage of Alamofire in an efficient and organised way.

EasyImplementationAlamoFire Tutorial to demonstrate an efficient way of handling the APIs structure for your iOS Applications. Prerequisites Swift 5 X

null 0 Jan 3, 2022
iOS client for the Brewfactory project - brew your own beer

BrewMobile iOS client for the Brewfactory project. Read the stories of upgrading BrewMobile to ReactiveCocoa & Swift on AllTheFlow. What is this? App

brewfactory 195 Dec 18, 2022
Shawn Frank 2 Aug 31, 2022
The core LibP2P Interfaces / Protocols and Abstractions backing the swift-libp2p project

LibP2PCore The core LibP2P Interfaces / Protocols and Abstractions backing the swift-libp2p project Table of Contents Overview Install Usage Example A

null 4 Dec 28, 2022