Tag Archives: Swift

How to add the SwiftLint without pain

Why do you need SwiftLint?

  1. It speed ups code reviews, you stop wasting time on code formatting, force casting, and other common issues
  2. It improves the code quality, code becomes more readable, and maintainable

Integration

1. Add SwiftLint to a podfile

Or use another option from the official documentation.

2. Add this .swiftlint.yml config file to the project root folder

The main trick to make integration easy is to disable all rules at first.

3. Build a project, add additional rules to the disabled_rules section, if there are many warnings for them

4. Delete rules from the disabled_rules section one by one and fix all the warnings

5. Leave the trailing_whitespace and other rules that you don’t want to fix in the disabled_rules section

In the end, you will have something like this in your config file.

Some ideas on how to fix common code issues

Force Cast Violation: Force casts should be avoided. (force_cast)

Problem:

Solution:

Force Try Violation: Force tries should be avoided. (force_try)

Problem:

Solution:

Exceptions

In very rare cases you will not be able to fix the warning. For example, when you use a framework and you cannot easily change its API. Then you can switch off a SwiftLint rule for a particular code block using // swiftlint:disable rule_name and // swiftlint:enable rule_name comments.

Chaining example on RxSwift

This is one of the reasons I love RxSwift. It allows to chain requests beautifully.

Here I authorize user by getting auth token, then I request userInfo, then I request profile.

Получение строки, содержащей склонения дней дня день

Достаточно часто используемая штука, поэтому решил сохранить сниппет:

Использование:

Результат: 11 дней

Swift build failed. No errors.

This happened to me while I was writing in Swift 4.1 in XCode 9.3. I use RxSwift also. It never happened while I was writing in Objective C. There were no any logs in Report Navigator too. Project just compiled without errors, then failed. Couldn’t figure out why.

In my case what I did and it helped:

1. Commit changes in Git and then discard changes in XCode if it shows “M” near files
2. Clear derived data: Xcode -> Preferences -> location
3. Clean build folder: Shift + Cmd + Alt + K
4. Restart XCode

After this project tried to compile and showed errors. The error was here:

I passed wrong variable name in observer.onNext(timing). It should have been pTiming.

Asynchronous requests chaining using FlatMap operator in RxSwift

One of the main features of using RxSwift and RxCocoa or FRP is the possibility to chain several asynchronous requests and avoid callback hell. It can be achieved by using FlatMap operator and creating your own Observables from your asynchronous jobs like network requests or heavy calculations. But sometimes it is not simple to understand, how to do it. In this post I would like to show an example from one of my projects. The same can be applied to Objective C + ReactiveCocoa, the idea is the same.

First of all we should create Observables from different asynchronous requests. Then we can chain them using FlatMap operator. My example concerns a classic case – login and profile fetching. In many apps after logging in a user you have to request his profile in a separate request.

Usually you use MVVM with RxSwift. In a ViewModel you can create observables. In my case login() method creates an Observable from Alamofire request. In loadProfile() method Observable is created from ProfileService.

This is how you chain login and loadProfile requests. When they finish, you can do some job with a result profile. In this case I check a trial period and navigate to one of the views depending on a result.

Note that error for both requests is handled in one place using SCLAlertView. FlatMap operator maps a result of a first request to a second request and also flattens Observables. If you use just Map instead of FlatMap, the result of chaining will be an Observable of Observables.

Handling Swift JSONDecoder typeMismatch error while using Codable protocol

If you have a problematic JSON, which can contain number or string for some keys, you can decode object without that property and manually set that property after decoding.

For example, I have a Vehicle class inside HistoryItem. In Vehicle model_year can be empty String or non empty Int. Here I am decoding modelYear manually using NSDictionary and trying to get Int. Swift 4 cannot do it automatically.

This is my Vehicle class that is contained inside HistoryItem:

As you see, there is no model_year key in CodingKeys.

Creating a cold signal in ReactiveCocoa 7

For any case, there is an arbitrarily complex way to do it.

This prints “HELLO WORLD!”.