Collection View in Cross-Platform Swift Apps

Collection View in Cross-Platform Swift Apps

Create cross-platform dynamic UI views for Android & iOS platforms!

Introduction

📱🔍🔍 As mobile apps become increasingly popular and versatile, developers are tasked with creating dynamic user interfaces that can adjust to various screen sizes and orientations. One way to achieve this is through the use of collection views, which allow for the creation of a grid-like layout that can display UI elements with variable rows and columns.

🎨🤩 Collection views offer an incredible degree of flexibility and customization, allowing developers to create beautiful and functional user interfaces that stand out from the crowd. By adjusting the size, spacing, and content of each cell, you can create unique layouts that are tailored to the needs of your app and its users. Whether you want to display a collection of products, a gallery of photos, or a list of articles, collection views provide an intuitive and engaging way to present your content. Plus, with built-in support for animations, scrolling, and user interactions, collection views offer a seamless and immersive experience that keeps users coming back for more.

So, let's get ready to take your app's user interface to the next level with the power of collection views! 🚀🙌

IMPORTANT Announcement📢

The latest version of Nimble & SCADE editor has the following features:

  1. Swift 5.8 support: We can use all newly Swift 5.8 released features like the lazy keyword inside result builders, Collection downcasts in cast patterns, and concise magic file names are also now supported, etc. For more on Swift 5.8 features, please refer here.

  2. Custom LSP: We can now easily define the custom Language Server Protocol in Swift & Python in the Nimble editor. In this article, we will discuss in detail how to integrate the custom LSP.

  3. Collection View UI Widget: We can now create dynamic UI views with the variable number of rows and columns in the new release of the SCADE editor. In this article, we will build a SCADE example application to demonstrate the same.

Prerequisite

If you haven’t installed the SCADE IDE, download the SCADE IDE and install it on your macOS system. The only prerequisite for SCADE is the Swift language (at least basics). Also, please ensure the Android emulator or physical device is running if you want to run SCADE apps on an Android device.

Please install the latest version of Nimble editor if you want to try out the custom LSP support in Swift/Python, here.

Source Code

Configuration for Custom LSP

Assuming, you have the Nimble IDE installed and running. Navigate to the (Nimble → Settings… → Settings). You will be able to see the Settings where you can set the configurations for the Custom LSP. To create an external server, you will have to pass the following parameters:

  1. languages: This parameter refers to the list of languages supported by the custom Language Server Protocol (LSP) implementation. It is a mandatory parameter, and it typically specifies the programming or markup languages for which the LSP will provide language support and features.

  2. executable: The executable parameter is also mandatory and represents the path to the installed executable server. It is the actual server program that will handle the LSP communications and provide language-specific features and functionality.

  3. arguments: This optional parameter allows you to provide additional arguments or options that should be passed to the server executable when it is launched. These arguments can be used to customize the behavior of the server or enable specific features.

  4. environment: The environment parameter is an optional dictionary of environment variables and their corresponding key-value pairs. You can define environment variables specific to the server process using this parameter. These variables can influence the behavior of the server or provide configuration settings.

  5. initializationOptions: This optional parameter allows you to pass a list of values to the server during the initialization phase. These values should align with the specifications of the Language Server Protocol. The initializationOptions parameter enables you to provide any additional information or configuration required by the server during its initialization process., for more details, please, refer to the documentation of the Language Server Protocol

By configuring these parameters, you can set up and customize your custom LSP implementation to support specific languages, utilize the appropriate server executable, provide additional arguments, define environment variables, and pass initialization options as needed.

Adding original LSP server for Swift (shipped together with Xcode)

  1. Open the Settings file. You should be able to find the settings by clicking on (Nimble → Settings… → Settings).

  2. Edit editor.lsp.servers configuration:

editor.lsp.servers:  
- languages: ["swift"]  
  executable: "/usr/bin/sourcekit-lsp"

3. Restart the Nimble IDE.

This would add and register the system SourceKit LSP server for the Swift language.

Image description

Adding original LSP server for Python

To add the configuration for LSP Python server, follow the below steps:

1. Install the Python LSP server using pip (for more details please refer to the pip help) from Terminal:

pip install python-lsp-server
or, 
pip3 install python-lsp-server

2. Check the path of the LSP server in your system after installation

which pylsp

3. Open “Settings“ (Nimble → Settings… → Settings)

4. ​​Add an entry to the editor.lsp.servers setting as presented in the following code snippet:

editor.lsp.servers:    
 - languages: ["python"]
   executable: "/usr/local/bin/pylsp" # Add a path to on your system

5. Restart Nimble IDE.

If you want to check if the configuration is working as expected or not, you can create a .py file and try autocompletion & diagnostics which is inbuilt in Nimble editor.

Collection View SCADE App

As you are already aware that the latest version of SCADE now supports the Collection View and you can create it with ease for the dynamic number of UI items with the variable number of rows and columns. Let’s create the SCADE application in Swift to demonstrate the Collection View, compatible with both Android & iOS platforms.

Design the App

Let’s first create the UI of the application. In main.page file, add the following UI widgets by drag-drop to the editor.

  1. Horizontal/Vertical Collection: The parent UI widget will be the Horizontal Collection or Vertical Collection, which you will be able to see in the latest version of the SCADE editor. Drag and drop any one of these two widgets which will act as the container to hold the Template by default.

    In Horizontal CollectionView, the items are arranged by the number of rows defined in main.page.swift, and the columns are adjusted by the size of the items.

    Similarly for Vertical CollectionView, the items are arranged by the number of columns defined in main.page.swift, and it calculates the number of rows by default to wrap all the items.

  2. Image: Add the Image UI widget to the generated template widget of the Horizontal/Vertical Collection view which will display the image from assets.

Image description

Add the ScadeExtensions package dependency

As the next step, navigate to Package.swift and add the ScadeExtensions library via SPM.

// swift-tools-version:5.3

import PackageDescription
import Foundation

let SCADE_SDK = ProcessInfo.processInfo.environment["SCADE_SDK"] ?? ""

let package = Package(
    name: "CollectionView3",
    platforms: [
        .macOS(.v11)
    ],
    products: [
        .library(
            name: "CollectionView3",
            type: .static,
            targets: [
                "CollectionView3"
            ]
        )
    ],
    dependencies: [
      .package(name: "ScadeExtensions", url: "https://github.com/scade-platform/ScadeExtensions", .branch("main")),
    ],
    targets: [
        .target(
            name: "CollectionView3",
            dependencies: ["ScadeExtensions"],
            exclude: ["main.page"],
            swiftSettings: [
                .unsafeFlags(["-F", SCADE_SDK], .when(platforms: [.macOS, .iOS])),
                .unsafeFlags(["-I", "\(SCADE_SDK)/include"], .when(platforms: [.android])),
            ]
        )
    ]
)

The ScadeExtensions repository contains several utility functions to create better UI widgets. You can refer here for the details about CollectionView UI.

Let’s code the main.page.swift

Navigate to the main.page.swift and import the below-required packages.

import ScadeKit
import ScadeUI
import ScadeExtensions

Add a few images to the assets and rename them properly, eg. with numeric namings which will be easy to assign values programmatically.

Then, declare the Collection view widget by name defined in the main.page and assign rows and columns.

    if let cv = self.collectionView as? SCDWidgetsCollectionView {
      cv.elementProvider { (text: String, element) in
        element["image", as: SCDWidgetsImage.self]?.url = "Assets/\(text)"
      }

      cv.rows = 6
      cv.items = [
        "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg",
        "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg",
        "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg",
        "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg",
      ]
    }

After defining the CollectionView widget, inside the same block we need to define the element provides as the type of SCDWidgetsImage and pass the image URL to it. Then we can define the rows and columns. Please note that if we define only rows, then it will by default adjust the number of columns to wrap the content.

That’s it, a few lines of code is sufficient enough to code dynamically UI views. Let’s now run the application and test it on Android and iOS platforms.

Run the App on iOS/Android

In order to run the app on iOS/Android devices, please ensure the physical devices or simulator/emulator are up and running. SCADE apps can be run on SCADE emulators, iOS & Android devices as well as Apple and Android emulators.

You can also build the app for Android (APK/AAB) or iOS (IPA) to publish them to the respective app stores. You need to click on the App Name button and choose the device target accordingly.

iOS

Image description

Android

Image description

It was really interesting to create a cross-platform Swift app for iOS and Android to implement CollectionView 🎉. It is really cool. You can now easily integrate the CollectionView into your application projects 😊.