One simple trick to avoid unintentionally leaking your users private info

Image for post
Image for post

So imagine you have an app with a fairly simple model struct like this:

struct User {
var identifier: String
var handle: String
var name: String
var dateOfBirth: Date
var city: String
}

And to help you debug problems in your code, you have a remote-logging system that will send error messages to your backend (say, Sentry or something similar). The function looks like this:

func logError(_ description: String, userInfo: Any...) {
// ...
}

And then, whenever something fishy is happening, you use the logError function so that you can investigate it later:

logError("trying to edit the user that is not current…

Ready for some property wrappers?

Image for post
Image for post

It’s been almost three years since I wrote ”Do you often forget [weak self]? Here’s a solution”, which luckily resonated with many people. I’ll do a short recap, but if you want a deeper understanding of the topic you can go ahead and read that article first.

In short, the problem I was trying to solve was this: since traditional “protocol-based” delegation was seen by many (including me) as too cumbersome, alternative “closure-based” delegation was gaining traction. The concept is easy and, in pseudo-UIKit-code, looks something like this:

final class TextField {
var didUpdate: (String) -> () = { _ in }

/// ...

private func didFinishEditing() {
didUpdate(self.text) …

Stuck between UIKit and SwiftUI, many of us have a hard time finding the energy to push forward

Image for post
Image for post
Picture found at FindDoc

“I switched one of my side projects from SwiftUI to UIKit because that shit is not ready for prime time”

Since SwiftUI was announced last summer, I talked to many, many of my colleagues about their thoughts and feelings of this new piece of technology. Many, including myself, were excited. Who wasn’t dreaming of a first-class pure Swift UI framework? …

Let’s talk about closure-based delegation, retain cycles and generics

Okay, so today’s post is about delegation and how we can make it better with Swift. Without further ado, let’s introduce a standard example of Cocoa-style delegation in Swift:

  1. First, we create a delegate protocol restricted to classes
protocol ImageDownloaderDelegate: class {    func imageDownloader(_ imageDownloader: ImageDownloader, didDownload image: UIImage)}

2. Next, we implement our ImageDownloader

class ImageDownloader {

weak var delegate: ImageDownloaderDelegate?

func downloadImage(for url: URL) {
download(url: url) { image in
self.delegate?.imageDownloader(self, didDownload: image)
}
}

}

Note how delegate is marked as weak to prevent retain cycles. If you’re reading this post, I suggest you already know why we need this, but if you don’t, make sure to check out this brilliant article from NatashaTheRobot: iOS: How To Make Weak Delegates In Swift. …

You should not treat every piece of data the same way. Here’s why

Alright, no additional introductions this time — I’ll just cut straight to the point:

Only, only request a data in a synchronous manner if it’s coming directly from memory.

What do I mean by that? Well, if you have, for example, this code in your app:

let user = persistence.getUser(for: id)
label.text = user.name

You need to be absolutely sure that this data is already stored in the memory. It’s not being retrieved from the disk. It’s not being deserialized. It’s not being resolved in an algorithm of a skyrocketing complexity. It’s just there.

Folder of your iOS app — friendly and strongly-typed

Image for post
Image for post

Each one of your iOS apps has an associated container with it, where you, as a developer, can store basically anything you need. This is often referred to as a “sandbox”. Inside this sandbox, you can place files that serve different purposes — it could be user-visible documents, or database files, or caches, or some kind of metadata — anything. Basically, every persistence technique on iOS uses your app’s container to store info there. Thus, understanding how your app’s folder looks, how it’s structured and what files your put there is crucial for every iOS developer. …

Sometimes good coding practices lead to good UX

Image for post
Image for post

What happened?

Technically, today nothing stops you as a developer from unintentionally or accidentally making irreversible changes (e.g. deleting user data) without confirmation from the user. Of course, we try to mitigate this risk as much as possible, writing UIAlertController code all over the place (or even making cute convenience closure-based functions for this purpose), but the APIs we write do nothing to prevent this from happening.

For example, let’s imagine we have a class Images which is being injected straight to our view controllers

final class Images {

private var images: [UIImage]

func image(at index: Int) -> UIImage {
return images[index]
}

func add(_ image: UIImage) {
images.append(image)
}

func delete(imageAt index: Int) {
images.remove(at: …

Short story of “composition over inheritance” (including generics, yay!)

Disclaimer: this technique is relevant only if you create your layouts programmatically (without Interface Builder and Storyboards). If you want to take a deep look at why you should abandon Interface Builder, make sure to read this amazing piece by Zeplin crew. If, on the other hand, you want to strengthen your love for Interface Builder, I highly recommend this inspiring article from Lyft’s Scott Berrevoets.

What happened?

You may know this frustration: you have just made a perfect subclass of UITableViewCell, it looks and works just as you wanted it to, and everything is great… until you happen to need that exact same layout somewhere else in your app, and, most importantly — outside of table view. …

Type safe time calculations for Swift

In Cocoa, TimeInterval (ex NSTimeInterval) is the only thing that defines time. But, actually, it’s just a typealias for Double, and so it doesn’t have any descriptive meaning. Just a number. It’s not that obvious that Double means seconds in the world of Cocoa development. And that’s not very convenient too.

There are a lot of solution that aims to solve the convenience problem for you, providing the clear syntax like this:

let interval = 10.minutes + 15.seconds

And most of the time that’s just the extensions on Double with a few calculations:

extension Double {
var seconds: Double {
return self
}
var minutes: Double {
return self * 60
}
// so on…

Image for post
Image for post

Women’s Football 2017 is an open-source iOS & Apple Watch app dedicated to an upcoming Women’s Euro

Note: American readers should replace all occurrences of word “football” with “soccer”. Thank you for your understanding 😄

Women’s football is developing fast. Not only in terms of game quality, technical skills and tactics, but also in terms of cultural recognition and popularity among sport fans all over the world.

We are witnessing a rise of new stars — women players who are not just amazing footballers, but also role models for younger generations. Thanks to them, day after day football loses its doubtful masculine status, and more girls than ever choose football as their sports hobby or career. In most Nordic countries, youth football is already treated equally for boys and girls — that’s why we see women’s national teams of countries like Sweden, Norway, Denmark and Iceland among the leaders of women’s football. …

About

Oleg Dreyman

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store