https://kotlinlang.org logo
#feed
Title
# feed
s

Sam

12/06/2018, 11:49 AM
We’ve just released an open source K multiplatform library called
KotlinMultiPlatformStorage
https://github.com/netguru/KotlinMultiPlatformStorage. It simplifies persisting key-value data both on iOS and Android 🤖 🍎 in the common code modules. Feel free to use it and to contribute. If you’d like to read more about our story here is a blog post: https://www.netguru.co/codestories/what-weve-learned-by-developing-the-kotlin-multiplatform-storage-library
2
👍 1
🆒 5
We’d be also grateful for your reviews and opinions! 🙏
g

gildor

12/06/2018, 12:58 PM
Are there any particular reasons for creating new library instead of contribution to multiplatform-settings httpsthub.com/russhwolf/multiplatform-settings
t

thevery

12/06/2018, 12:58 PM
@gildor looks like internally it different on iOS - keychain instead of userdefaults
g

gildor

12/06/2018, 1:00 PM
Yes, I saw this difference, but it can be configurable on library level, use the same API etc Probably just make sense to introduce plugin system for library
👍 1
s

streetsofboston

12/06/2018, 1:26 PM
@russhwolf ^^^
k

kpgalligan

12/06/2018, 1:37 PM
I read the post. I'm not sure I'd agree that you should store everything in keychain. I mean, not that you shouldn't either, but it feels like an arbitrary decision, and on the Android side, shared prefs is just an xml file, so there's a disparity in security level. We've been using multiplatform-settings, which delegates to NSUserDefaults, and so far have had no issues. I'd love to see everybody building mobile libraries push to 4.10 on gradle, but I think everybody's waiting for 1.3.20+
Details aside, though, more people working on multiplatform libraries is great
To clarify "and so far have had no issues", we're not storing sensitive data. If you were, however, you shouldn't be using SharedPreferences, so the security disparity is going to make the library difficult to use. You'd need the keychain equivalent on Android
s

Sam

12/06/2018, 1:46 PM
Thanks for all the comments. Regarding
multiplatform-settings
, we were studying its implementation carefully and decided that it would be quite a lot changes to make if we’d decide develop it. We had a different vision of the library internal mechanisms, and as the result, there were a few motivations for working on a new library project. First, although the API for key-value storing is similar, we’ve designed the mechanism for base storage class instantiation quite differently. We wanted it to be fully compatible with the new ‘kotlin-multiplatform’ plugin. In the effect, there is no need to pass
Context
manually to create it on the 🤖 side. All in all, we are just instantiating a class like this: `MultiPlatformStorage()`(https://github.com/netguru/KotlinMultiPlatformStorage/blob/6841f94e657a3d9e746e3b8555575f6388cbd706/sampleapp/app/src/commonMain/kotlin/com.netguru.sample/MainPresenter.kt#L11) This way there is no need to implement any Factory instances on the platform-specific modules. Everything is just done in the common module. Next, we wanted to use Keychain API instead of UserDefaults. Apart from that, it seemed easier to build it our way from scratch and we just wanted to give it a try.
@kpgalligan Sure, we shouldn’t store any sensitive data inside SharedPrefs. But, if we have the Keychain on the iOS why not use it instead of NSUserDefaults even for non-sensitive data? 😉
Also we plan to improve the Android implementation not rely on SharedPreferences in the future
k

kpgalligan

12/06/2018, 1:56 PM
@Sam I don't know, but the blog post didn't explain it. I would start with what I said. If you're going to be insecure with your data on Android, why do something more involved on iOS? I would hardly call the issue "settled" in iOS land. There's this kind of stuff: https://stackoverflow.com/a/49567649/227313
👍 1
SharedPreferences and NSUserDefaults are fantastic, if you don't have secure data. If you do, you should do something else. That's all.
There are perhaps other issues, but welcome to computers:

https://www.youtube.com/watch?v=dyIqM-6CyXY

s

Sam

12/06/2018, 1:59 PM
That’s a good point actually, thanks @kpgalligan. We need to discuss it for sure.
k

kpgalligan

12/06/2018, 2:00 PM
Some questions. What does "We wanted it to be fully compatible with the new ‘kotlin-multiplatform’ plugin" mean? I don't think that has anything to do with Context, and unless you're talking about future compatibility, you're using the "old" plugin right now, yes? Also, I think the 'provider' init is clever, but I'm also super anti-ContentProvider, so you should probably explain that whole thing a lot more to potential users.
Or make that configurable. I'd prefer to pass my app context to your library rather than have it materialize on it's own.
👍 1
r

russhwolf

12/06/2018, 2:59 PM
This is all very interesting, if a little surprising. I'll have to take a closer look at the different implementation choices you guys made when I have some time. In general I love seeing more players in this space. That said, given that you're building essentially the same functionality and were studying my implementation anyway, I would have appreciated a heads-up and a chance to talk about where your implementation needs differ. On Keychain vs NSUserDefaults, I briefly considered both but I preferred NSUserDefaults because I think it provides the same abstraction as SharedPreferences. This isn't intended as something to use for app secrets in plaintext. If the Android solution is less secure, I wanted the iOS solution to be similar so there's no confusion on that point when an iOS developer unfamiliar with SharedPreferences starts using it. On Context and ContentProvider, I echo Kevin's thoughts. That's always felt like a weird hack to me ever since Firebase introduced it. That said I'm open to including something like that as an optional extra dependency if there's interest. Hard to know though because I haven't received a ton of feedback on my api choices. Speaking of api, nothing forces you to use a Factory in multiplatform-settings. You can always pass SharedPreferences and NSUserDefaults directly from your platform code, as long as you have an
expect
declaration to reference it from common. The purpose of the Factory is really so that you can pass a name in from common while only needing to inject a Context once, which is helpful if you want to organize multiple different storage objects in common code. On gradle plugins: I've done partial work on updating that but was blocked by publishing support. Open to PRs if other people have it figured out, but I also plan to take another stab at it soon since apparently some folks have it working. If nothing else, though, you can certainly consume the lib from the new plugin even though it's written with the old ones. And that's definitely a different issue than Context injection.
👍 2
k

kpgalligan

12/06/2018, 3:14 PM
The Firebase hack is interesting. It doesn't look like there's anything much going on here, but as a general fyi, if you have multiple processes in an app, that gets run multiple times. I found that out the hard way building a crash reporter also (way before firebase). I went to the deep dive talk when firebase crash was new, and they apparently also found out the hard way.
s

Sam

12/06/2018, 3:30 PM
Thanks for the comments. I agree with the doubts related to Context injection hacks. Regarding the libs, I think it would probably make more sense to move towards developing KotlinMultiplatformStorage lib into a “secure storage” direction, e.g. using Keystore on the Android/JVM side. It doesn’t make any sense to me to duplicate
multiplatform-settings
purpose and capabilities 🤔 All in all, it’s just highly experimental “product” atm. Also, I’m open to contributing to
multiplatform-settings
too
k

kpgalligan

12/06/2018, 3:33 PM
Well, I think there are going to be multiple versions of everything and that's OK. As of today I think there are 4 separate logging libraries in some form of "published" for KMP. I know there are roughly 3 sqlite libs, 1 by me, and about to be another (also by me, deprecating the other one). Lots of similars is how things go.
For settings, I've been thinking there's maybe an entirely different solution for all sides. Take what's good about the different providers and implement using a kotlin io lib, coroutines aware (if useful), etc. Shared prefs and nsuserdefaults both have their own quirks, and aren't exactly rocket science.
g

gildor

12/06/2018, 4:09 PM
For Android there are a few solution for encrypted preferences, https://github.com/scottyab/secure-preferences https://github.com/yandextaxitech/binaryprefs (nice project with own efficient implemntation) Also probably possible to use keystore for that
👍 2
k

kpgalligan

12/06/2018, 4:13 PM
Yeah, something like https://github.com/yandextaxitech/binaryprefs. Rather than delegate to platform defaults, a new implementation that makes sense.
l

louiscad

12/21/2018, 7:04 PM
About App Context, why not just use Splitties
appCtx
? (Full disclosure: I made it, and it supports multiprocess, and libraries)
👀 1
k

kpgalligan

12/21/2018, 7:16 PM
Link?
See it
19 Views