Say Goodbye to “Index out of range” — Swift

Wendy Liga
3 min readNov 18, 2019

--

How to avoid fatal mistakes on array Swift.

Thanks to undraw.co for a great illustration

As a Developer, Array is one of the crucial tools we use to build our code. Array create this possibility to save the collection of object that organizes by index, and it’s very powerful for code that handling looping or handling dynamic data.

One common error every array user ever faced is “Fatal error: Index out of range”.this error was caused by accessing an index that array doesn’t even have in the first place.

This error is undetectable on build time and can only show up on runtime which will be fatal on production or on distributed code. The solution here is to check whether the array is containing the index before accessing the index.

let names = ["Jhonson", "Erica", "Tom"]if names.indices.contains(0) {
print(names[0])
}

by checking if array contains that index or not before use it, we can make sure that we will not ever face “Index out of range” (if there’s no other thread/async code that changes the array value) because we can make sure that this array is containing index we want to access.

Under the hood, `indices.contain` will loop the entire array to check whether there’s the index that matches with array item. If you operate a big array, this solution will not really efficient. Thanks to the un-order type of array, we can always make sure that array will always have the upper index or lower index that represents the entire array item count.

if index>= names.startIndex && index< names.endIndex {
print(names[index])
}
Wow

So rather than looping the entire array, we only need to check whether our desire index is inside the lower index or upper index range.

Boilerplate Code

But what about if I want to access the index of array a lot, I will create a lot of boilerplate code :(

Repeat Repeat Repeat

If you want to access a lot index of array a lot, you will start creating a lot of boilerplate code. Extension comes in handy and we can utilize its power

extension Collection where Indices.Iterator.Element == Index {
public subscript(safe index: Index) -> Iterator.Element? {
return (startIndex <= index && index < endIndex) ? self[index] : nil
}
}

So we can use extension of Collection but only apply it on indices that use Index, in this case, array. we don’t want to apply this to other Collection like Set or Dictionary.

how to use

print(names[safe: 0])

It will return the value or if the array doesn’t contain the index, it will automatically return nil. is that neat?

Update

You can check my SwiftKit, my own personal swift helper that contain this array safe access, you can check it here

Wrap Up

The array as one of the crucial tools for a lot of developers to write code is very powerful for handling dynamic data. but the caveat, we need to make sure we access the right index if we don’t want to face “Index out of range”. the key is to check whether the array contains index we want to access or not.

Thanks for your time on reading my medium post, Hope it can be helpful :)

--

--

Wendy Liga
Wendy Liga

Written by Wendy Liga

Learning Driven Life • iOS Software Writer at Tokopedia • Exploring Swift and Anything that Sounds Fun • Open Source Enthusiast

Responses (5)