# 👷‍♂️ Classes and Shared Objects ## Navigation - [🏡 Native modules made easy with Expo](/gYH9xz-oR2ai0Yih8if50w) - [👶 First Steps](/ANE6NSUlTSimTIrN-gMsBw) - [⚙️ Native Module](/mAIt0ctDTvSL5xV4uE9nWQ) - [📈 Passing data to view](/_gWWp8uoQwGkqKcEyfk8Tg) - [📚 View Props](/96IjlLNDRvydILdkbfaA5A) - [🔥 View Events](/PQWXYmxLRCebmLfx3Fh_gg) - [🏞️ View Functions](/DcjStCFdT6euzWqnJqCL6w) - [👉 👷‍♂️ Classes and Shared Objects](/__42gVw8RqiIgfSbVseIvw) - [📊 Views and shared object](/IgHyIAHQQPCbeBD74Ri4BA) --- ## Classes ### Task 1 Export from `ChartModule` an empty native class the is called `Class`. :::spoiler :robot_face: Android :open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt` ```kotlin Class("Class") { } ``` ::: :::spoiler :apple: iOS :open_file_folder: File `ios/ChartsModule.swift` ```swift Class("Class") { } ``` ::: <br /> 📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/7e91e3e291eec8019af6b4bc9343c0ace588f9c5) --- ### Task 2 Add a native constructor to the exported class. This constructor should have the option to receive an integer parameter and also set the property (named `property`). If no value is provided, the default value of `10` should be used. :::spoiler :robot_face: Android :open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt` ```kotlin Constructor { self: JavaScriptObject, value: Int? -> self.setProperty("property", value ?: 10) } ``` ::: :::spoiler :apple: iOS :open_file_folder: File `ios/ChartsModule.swift` ```swift Constructor { (this: JavaScriptObject, value: Int?) in this.setProperty("property", value: value ?? 10) } ``` ::: <br /> 📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/f1b3120006a917079817ea38d4d097df859255a6) --- ### Task 3 Add an async function named `modifyProperty` that will multiply the value of the previously set property by itself. :::spoiler :robot_face: Android :open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt` ```kotlin Function("modifyProperty") { self: JavaScriptObject -> val p = self.getProperty("property").getInt() self.setProperty("property", p * p) } ``` ::: :::spoiler :apple: iOS :open_file_folder: File `ios/ChartsModule.swift` ```swift Function("modifyProperty") { (this: JavaScriptObject) in let p = this.getProperty("property").getInt() this.setProperty("property", value: p * p) } ``` ::: <br /> 📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/ce81903864c6b8866d8df905f6dad24d8aa8bd55) --- ### Task 4 Create a duplicate of the `modifyProperty` function and make it asynchronous. :::spoiler :robot_face: Android :open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt` ```kotlin AsyncFunction("modifyPropertyAsync") { self: JavaScriptObject, promise: Promise -> appContext.executeOnJavaScriptThread { val p = self.getProperty("property").getInt() self.setProperty("property", p * p) promise.resolve(null) } } ``` ::: :::spoiler :apple: iOS :open_file_folder: File `ios/ChartsModule.swift` ```swift AsyncFunction("modifyPropertyAsync") { (this: JavaScriptObject, promise: Promise) in guard let context = appContext else { throw Exceptions.AppContextLost() } context.executeOnJavaScriptThread { let p = this.getProperty("property").getInt() this.setProperty("property", value: p * p) promise.resolve() } } ``` ::: <br /> 📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/c89c325700d85eb2546b3917d02c0deebdf60460) --- ### Task 5 Add a function that returns an anonymous object. This object should contain a function called `calculate`, which receives three integers and returns their sum. :::spoiler :robot_face: Android :open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt` ```kotlin Function("createAnonymousObject") { return@Function Object { Function("calculate") { a: Int, b: Int, c: Int -> a + b + c } } } ``` ::: :::spoiler :apple: iOS :open_file_folder: File `ios/ChartsModule.swift` ```swift Function("createAnonymousObject") { Object { Function("calculate") { (a: Int, b: Int, c: Int) in a + b + c } } } ``` ::: <br /> 📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/89c4e4f09065034c82730f78eb427adad44ff372) --- ## Shared Objects ### Task 6 Create a shared object that represents a list of integers. This object should allow for the addition and retrieval of elements, as well as checking its size. :::spoiler :robot_face: Android :open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt` ```kotlin class SharedList<T> : SharedObject() { private val data = mutableListOf<T>() val size: Int get() = data.size fun add(newElement: T) { data.add(newElement) } operator fun get(index: Int): T { return data[index] } } ``` ::: :::spoiler :apple: iOS :open_file_folder: File `ios/ChartsModule.swift` ```swift class SharedList : SharedObject { private var data: [Int] = [] var size: Int { data.count } func add(_ newElement: Int) { data.append(newElement) } subscript(index: Int) -> Int { get { return data[index] } } } ``` ::: <br /> 📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/8d5d3cdebbb1affbf812e4fd853cc41f3eadc8f1) --- ### Task 7 Export a shared list within a native class. The exported structure's JavaScript representation must follow an interface: ```typescript interface SharedList { new (): SharedList; readonly add: (newValue: number) => void; readonly get: (index: number) => number; readonly size: () => number; readonly addAsync: (newValue: number) => Promise<void>; readonly getAsync: (index: number) => Promise<number>; readonly sizeAsync: () => Promise<number>; } ``` :::spoiler :robot_face: Android :open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt` ```kotlin Class(SharedList::class) { Constructor { return@Constructor SharedList<Int>() } Function("add") { sharedObject: SharedList<Int>, newValue: Int -> sharedObject.add(newValue) } Function("get") { sharedObject: SharedList<Int>, index: Int -> sharedObject[index] } Function("size") { sharedObject: SharedList<Int> -> sharedObject.size } AsyncFunction("addAsync") { sharedObject: SharedList<Int>, newValue: Int -> sharedObject.add(newValue) } AsyncFunction("getAsync") { sharedObject: SharedList<Int>, index: Int -> sharedObject[index] } AsyncFunction("sizeAsync") { sharedObject: SharedList<Int> -> sharedObject.size } } ``` ::: :::spoiler :apple: iOS :open_file_folder: File `ios/ChartsModule.swift` ```swift Class(SharedList.self) { Constructor { return SharedList() } Function("add") { (sharedObject: SharedList, newValue: Int) in sharedObject.add(newValue) } Function("get") { (sharedObject: SharedList, index: Int) in sharedObject[index] } Function("size") { (sharedObject: SharedList) in sharedObject.size } AsyncFunction("addAsync") { (sharedObject: SharedList, newValue: Int) in sharedObject.add(newValue) } AsyncFunction("getAsync") { (sharedObject: SharedList, index: Int) in sharedObject[index] } AsyncFunction("sizeAsync") { (sharedObject: SharedList) in sharedObject.size } } ``` ::: <br /> 📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/bb42e64a68f83bc91c3876c796af548f8376d164) --- ## [📊 Views and shared object](/IgHyIAHQQPCbeBD74Ri4BA)