One of the potential myths of Xojo is that it is low code. In some places, this may be true, but in t’other thread, I highlighted some examples of where this is false.
What I’d like to do is to share some more examples that have impressed me, and I encourage others to do the same in their languages.
This is the code that de-serializes my data model from JSON. By including it in this method, it doesn’t matter how the file is opened in the app, even from using the “Versions” option in the file menu.
init(configuration: ReadConfiguration) throws {
guard let data = configuration.file.regularFileContents
else { throw CocoaError(.fileReadCorruptFile) }
self.items = try JSONDecoder().decode( [MRAFunctionalityItem].self, from: data )
}
If the de-serialization fails for what ever reason, the app auto displays the error message to the customer. I don’t have to do anything to get that.
In the opposite direction, this code serializes my data model, and again, by putting the code in this method, it can be called when the user saves, when the OS auto saves document etc.
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let data = try JSONEncoder().encode( self.items )
return .init(regularFileWithContents: data)
}
This code below is one of the latest I’ve learned and I think it’s pretty incredible. It not only displays a list of objects in an array, it also manages that list. If the customer rearranges the data in the list view, the data is updated to match, same with using the swipe action to delete data. This list will auto update if I change the data from anywhere else in the application. The list is fully native for each platform. In a document based app, all these actions auto generate an Undo and auto update when the customer performs an Undo.
List( $document.data.app.features, editActions:.all, selection: $multiSelection ) { $item in
TextField( "Field Hint", text: $item.title )
.focused( $focusedField, equals: item.id )
.tag( item.id )
}
Those dollar signs in front of variable names, indicate that I want a binding, which means the view can update the property and if the property changes, the view should auto update.
That .focused modifier allows to me set focus on that field by simply setting a property called focusedField to the id of the item.
This next one is one of my favorites, code in-between these braces will now run as a pre-emptive thread on the efficiency core of the Apple Silicon processor, with full access to the object’s properties.
Task( priority: .background ) {
<code>
}
This code allows me to store temporary scene specific data, it is preserved between application re-launches, but is disposed of when the customer closes the window.
@SceneStorage( "editMode" ) var editMode: Bool = false
If I want to store a variable in the application preferences…
@AppStorage( "editMode" ) var editMode: Bool = false
While I like to annotate my variables with the defined type, it is not needed in Swift. I could just write var editMode = false
.
Lastly, if I want to animate a view change (adding a row to a list or more), it can be done by simply wrapping that code in a withAnimation closure.
withAnimation( .bouncy ) { document.data.app.features.append( newItem ) }
Or I can attach animation modifiers to views that react on a property change.