Sign in

When talking about syncing local data with the remote data source, it’s about Insert, Delete and Update entity in the local database according to the response of API. Considering creating, deleting or updating occur in an arbitrary position of a paging API, the synchronization becomes a little complicated. You can simply delete all of them first and then re-create entities again, or create new entities using brute force with a specific merge policy, or manipulate the local database under the instruction on the API which indicates which data need to be created, updated or deleted.

The strategy in this story…


There are two essential ideas in a well-designed MVVM: unidirectional data flow and weak reference to the view.

The flow of data in MVVM is unidirectional, the data was aroused from user or system event, and then it flows to viewModel, model, and view at last. You can implement the unidirectional by getting rid of having a controller reference in ViewModel. But how to update view without strong reference to view? In Android development, Jetpack provides LiveData to view owners(activity or fragment) for observation. …


I love programming in Android and iOS platforms with Kotlin and Swift, I will demonstrate the difference and similarity of enumeration using code in this post, it is part of this language comparison series.

Definition of Enumeration

Kotlin

In Kotlin, each enum constant is an object.

enum class Direction { 
NORTH, SOUTH, WEST, EAST
}

Swift

But in Swift, an enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code. Each enum case is a value.

enum Direction {
case north
case…

In the early stage of iOS development, we may need some mocking data or generated data to feed UI. And there are some awesome JS libraries which we can leverage to speed up iOS development. In this story, I will take faker.js as an example to show you how to leverage JS code in Swift.

What is faker.js

faker.js — generate massive amounts of fake data in the browser and node.js

faker.js is a great collection of common data, such as country, user name, email, avatar, etc.

name: firstName, lastName, findName, jobTitle, gender, prefix, suffix, title, jobDescriptor, jobArea, jobTypeaddress: zipCode, zipCodeByState, city…

This story is an extension of the previous stories of Data Binding with KeyPath Part1 and Part2.

The two stories are all about one-way and two-way data binding with KeyPath. And this story will continually demonstrate some applications of KeyPath on validation, calculation, and collection and will show you how awesome it is.

KeyPath in Validation

If you are familiar with the following code of guards, you will find it’s very annoying to write these duplicate code like me.

guard let name = nameField.text?.trimmingCharacters(in: .whitespaces), name.isUserName else {    nameField.becomeFirstResponder()
}
guard let email = emailField.text?.trimmingCharacters(in: .whitespaces), email.isEmail else { emailField.becomeFirstResponder()
}
guard let…

This story is about how I implement one-way and two-way data binding with Swift KeyPath. Before reading this story, you may need to check out part1 to know which data-flow strategy I’m taking.

Why KeyPath?

\TypeName.path

1. Dynamic and Consistency

Key-path expressions provide a dynamic and consistent way to access and update data. The type can be any concrete or generic type, including normal struct and UI Components which are the two important endpoints of data binding.

var model = User()
var view = UITextField()
model[keyPath: \User.name] = “Tonny”
view[keyPath: \UITextField.text] = “Tonny”
view[keyPath: \UITextField.text] = model[keyPath: \User.name]
model[keyPath: \User.name] = view[keyPath: \UITextField.text]

It also has…


Android provides data binding to listen to the model’s change and update binding views. That’s where I love Android development more than iOS development. In this story, I’ll implement data-binding with Swift KeyPath, and probably you have a better idea. Welcome to comment.

From this form design, you can easily find there are a data model and related text fields and choice buttons. It’s easy to implement it in Android with data binding: a data class, a layout with data declared in the XML, and a couple of binding expressions. That’s it. …


This post is about how to use only one RecyclerAdapter to deal with multiple recycler views with Android Jetpack, and it’s inspired by a post from Anton Stulnev.

In this demo, I use PagedListAdapter, but you don’t have to. For the complete project written in Android Jetpack, you can view it in my Github. It contains iOS and Android version.

RecyclerItem, an interface for all UI model of recycler view

To eliminate multiple recycler view adapters, generic is a great way to reduce redundancy. But first, let’s create an abstract interface for UI model which is presented in recycler view.

  • The layoutId is the layout resource id for its view…

Sometime we have to write ViewModel with argument of Int, String, or other type. And copy paste method always came to my mind first. So it will become as following code, obviously on redundancy.

We may find a better solution with generic, reflection andmodel.getConstuctor to retrieve the right constructor and then create the instance.

class AndroidViewModelFactory<P : Any>(
private val application: Application,
private val parameter: P
) : ViewModelProvider.NewInstanceFactory() {
... modelClass.getConstructor(
Application::class.java,
parameter::class.java
).newInstance(application, parameter)

But we have to considerate the difference of reflection in java and kotlin, e.g. 0::class.java return java.lang.Integer, but the constructor need kotlin Int


declarative api test

From previous story, you may know how I utilised `yaml + ejs + faker + ava + superagent` to test api in declarative way.

In essence, it transfers imperative obj.function(parameter) into the following declarative format in yml file.

obj:
function:
name: value

so we can send http requests with superagent and assert with ava in following yml file.

superagent:
set:
Authorization: <%-$jwt%>
send:
pageIndex: <%-$pageIndex%>
pageSize: 10
ava:
is:
status: 200

However, ava has very basic yes/no assert. It has no function to assert a value in an array of [0, 1, 2], or to assert a value is non-empty…

Tonny

Mobile developer@NZ. iOS, Android, React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store