How to create 2d fixed-size array in Swift

Recently I am doing some code tests and found that fixed-size array creation is not as simple in Swift compare to other languages, i.e.

// In C++

int array1[64];    // 1-dimension array size 64
int array2[64][64] // 2-dimension array size 64x64

After a bit digging, the way to do it in swift:

// in Swift:

var array1 = [Int?](repeating: nil, count: 64) // 1 dimension array

var array2 = [[Int?]](
 repeating: [Int?](repeating: nil, count: 64)
 count: 64
) // 2-dimension array size 64x64

// Access it just like normal

array2[4][2] = 42
print(array2[4][2]) // output: 42

So a 3d array would be:

// in C++

int array3[3][3][3];

// in Swift !!!!!!

var array3 = 
  repeating: [[Int?]](
    repeating: [Int?](
      repeating: nil,
      count: 3),
  count: 3),
count: 3)

Now you know how, you can try 7-dimension, happy coding 🍳

Mindflow: Flutter deal with Future! in 6 Steps

With a Swift background, Flutter+Dart require a different thought-process. Future<T> is associated with async calls and it could be hard to re-route your brain in a one go. In this article I am sharing my experience on how the mindflow when dealing with Future<T> using SharePreferences as an example, from start to a 1-liner in 6 steps.

1. Direct mindflow:

This is how a method looks like with the consideration of existing of Future<T>, it doesn’t work since SharedPreferences.getInstance() returns Future<SharedPreferences> instead of SharedPreferences.

static int getCount(){

// This will return Future<SharedPreferences>, unwarp is needed.
final preferences = SharedPreferences.getInstance();

// Future<SharedPreferences> causes error
// because SharedPreferences has .getInt()
// but Future<SharedPreferences> does not have .getInt()
final value = preferences.getInt("attributeName");

return value;

2. Fix the Future!

To handle Future<SharedPreferences>, add async and await. But the value can be null!

// async is needed to use the keyword await
// async also require Future<int> instead of int
static Future<int> getCount() async {

// Keyword await "unwarp" Future<SharedPreferences> to SharedPreferences
final preferences = await SharedPreferences.getInstance();

// .getInt() works normally now,
// but null can be return if "attributeName" does not have a value
final value = preferences.getInt("attributeName");

return value;

3. Fix the null value!

Change the final to var for value to be validated:

// async is needed to use the keyword await
static Future<int> getCount() async {

// Good now
final preferences = await SharedPreferences.getInstance();

// Change final to var so value can be validated
var value = preferences.getInt("attributeName");

// Validating value
if (value == null){
value = 0;

return value;

4. Shorthand for if …

if … could be a bit blocky, we could replace it with (condition) ? (true) : (false):

static Future<int> getCount() async {

// Shortent this too
final pref = await SharedPreferences.getInstance();

// Replace if with (condition) ? (true) : (false)
var value = pref.getInt("attributeName") == null ? 0 : pref.getInt("attributeName");

return value;

5. Remove more

Future<T> can be stacked with (await Future<T>) to get T within the async method.

static Future<int> getCount() async {

// Remove this line too

// Replace it with (await Future<SharedPreferences>) to get SharedPreferences
var value = (await SharedPreferences.getInstance()).getInt("attributeName") == null ? 0 : (await SharedPreferences.getInstance()).getInt("attributeName");

return value;

6. One-liner!

1-liner, just return the value :

static Future<int> getCount() async {
return (await SharedPreferences.getInstance()).getInt("attributeName") == null ? 0 : (await SharedPreferences.getInstance()).getInt("attributeName");