Foundation support for Skip apps.
See what API is currently implemented here.
SkipFoundation vends the skip.foundation
Kotlin package. It is a reimplementation of Foundation for Kotlin on Android. Its goal is to mirror as much of Foundation as possible, allowing Skip developers to use Foundation API with confidence.
SkipFoundation also implements portions of the CryptoKit API.
SkipFoundation depends on the skip transpiler plugin as well as the SkipLib package.
SkipFoundation is part of the core SkipStack and is not intended to be imported directly.
The module is transparently adopted through the translation of import Foundation
into import skip.foundation.*
by the Skip transpiler.
- SkipFoundation includes source code from the UrlEncoderUtil library to implement percent escaping.
SkipFoundation supports many of the Foundation framework's most common APIs, but there are many more that are not yet ported. See Foundation Support.
When you want to use a Foundation API that has not been implemented, you have options. You can try to find a workaround using only supported API, embed Kotlin code directly as described in the Skip docs, or add support to SkipFoundation. If you choose to enhance SkipFoundation itself, please consider contributing your code back for inclusion in the official release.
We welcome contributions to SkipFoundation. The Skip product documentation includes helpful instructions and tips on local Skip library development.
The most pressing need is to implement more of the most-used Foundation APIs. To help fill in unimplemented API in SkipFoundation:
- Find unimplemented API.
- Write an appropriate Kotlin implementation. See Implementation Strategy below.
- Edit the corresponding tests to make sure they are no longer skipped, and that they pass. If there aren't existing tests, write some. See Tests.
- Submit a PR.
Other forms of contributions such as test cases, comments, and documentation are also welcome!
The goal of SkipFoundation is to mirror the Foundation framework for Android. When possible, SkipFoundation
types wrap corresponding Kotlin or Java foundation types. When a SkipFoundation
type wraps a corresponding Kotlin or Java type, please conform to the skip.lib.KotlinConverting<T>
protocol, which means adding a .kotlin()
function:
#if SKIP
extension Calendar: KotlinConverting<java.util.Calendar> {
public override func kotlin(nocopy: Bool = false) -> java.util.Calendar {
return nocopy ? platformValue : platformValue.clone() as java.util.Calendar
}
}
#endif
You should also implement a constructor that accepts the equivalent Kotlin or Java object.
SkipFoundation's Tests/
folder contains the entire set of official Foundation framework test cases. Through the magic of SkipUnit, this allows us to validate our SkipFoundation API implementations on Android against the same test suite used by the Foundation team on iOS.
It is SkipFoundation's goal to include - and pass - as much of the official test suite as possible.
The following table summarizes SkipFoundation's Foundation API support on Android. Anything not listed here is likely not supported. Note that in your iOS-only code - i.e. code within #if !SKIP
blocks - you can use any Foundation API you want.
Support levels:
- β β Full
- π’ β High
- π‘ β Medium
- π β Low
Support | API |
---|---|
π |
|
π‘ |
|
π‘ |
|
π |
|
β | CocoaError |
β | ComparisonResult |
π |
|
β | CustomNSError |
π‘ |
|
π‘ |
|
π’ |
|
π‘ |
|
β | DateInterval |
π |
|
π |
|
π’ |
|
β | HTTPURLResponse |
π’ |
|
π‘ |
|
π‘ |
|
β | JSONDecoder |
β | JSONEncoder |
β | JSONSerialization |
β | Locale |
β | LocalizedError |
β | LocalizedStringResource |
β | Logger |
β | Notification |
π‘ |
|
β | NSError |
β | NSLock |
β | NSLocalizedString |
β | NSRecursiveLock |
π’ |
|
π’ |
|
π |
|
π’ |
|
β | POSIXError |
π‘ |
|
π |
|
π |
|
β | RecoverableError |
π’ |
|
β | StringLocalizationValue |
β | func strlen(_ string: String) -> Int |
β | func strncmp(_ str1: String, _ str2: String) -> Int |
π‘ |
|
π’ |
|
β | UnknownNSError |
π’ |
|
π’ |
|
β | URLError |
β | URLQueryItem |
π‘ |
|
β | URLResponse |
π‘ |
|
π‘ |
|
π’ |
|
π’ |
|
π’ |
|
π’ |
|
π’ |
|
SkipFoundation vends portions of the CryptoKit framework by delegating to the built-in Java implementations:
SHA256
SHA256Digest
SHA384
SHA384Digest
SHA512
SHA512Digest
Insecure.MD5
Insecure.MD5Digest
Insecure.SHA1
Insecure.SHA1Digest
HMACMD5
HMACSHA1
HMACSHA256
HMACSHA384
HMACSHA512
Each supported algorithm includes the following API:
associatedtype Digest
public static func hash(data: Data) -> Digest
public func update(_ data: DataProtocol)
public func finalize() -> Digest
The returned Digest
in turn acts as a sequence of UInt8
bytes.
Skip implements much of Foundation.FileManager
, which should be
the primary interface for interacting with the file system.
The app-specific folder can be accessed like:
// on Android, this is Context.getFilesDir()
let folder = try FileManager.default.url(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: false)
And to read and write to the cache folders:
// on Android, this is Context.getCachesDir()
let caches = try FileManager.default.url(for: FileManager.SearchPathDirectory.cachesDirectory, in: FileManager.SearchPathDomainMask.userDomainMask, appropriateFor: nil, create: false)
And the system temporary folder can be accessed with:
let tmpdir = NSTemporaryDirectory()
None of the other FileManager.SearchPathDirectory
enumerations are implemented in Skip.
Both Data
and String
have the ability to read and write to and from URLs and path strings.