Foundation support for Skip Lite transpiled Swift.
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
}
}
#endifYou 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 |
| β |
|
| β | 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:
SHA256SHA256DigestSHA384SHA384DigestSHA512SHA512DigestInsecure.MD5Insecure.MD5DigestInsecure.SHA1Insecure.SHA1DigestHMACMD5HMACSHA1HMACSHA256HMACSHA384HMACSHA512
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 = URL.documentsDirectory
// which is shorthand for the following:
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 = URL.cachesDirectory
// which is shorthand for the following:
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:
// on Android, this will be the same as Context.getCachesDir()
let tmpdir = URL.temporaryDirectory
// you can also use:
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.
This software is licensed under the GNU Lesser General Public License v3.0, with the following linking exception to clarify that distribution to restricted environments (e.g., app stores) is permitted:
This software is licensed under the LGPL3, included below. As a special exception to the GNU Lesser General Public License version 3 ("LGPL3"), the copyright holders of this Library give you permission to convey to a third party a Combined Work that links statically or dynamically to this Library without providing any Minimal Corresponding Source or Minimal Application Code as set out in 4d or providing the installation information set out in section 4e, provided that you comply with the other provisions of LGPL3 and provided that you meet, for the Application the terms and conditions of the license(s) which apply to the Application. Except as stated in this special exception, the provisions of LGPL3 will continue to comply in full to this Library. If you modify this Library, you may apply this exception to your version of this Library, but you are not obliged to do so. If you do not wish to do so, delete this exception statement from your version. This exception does not (and cannot) modify any license terms which apply to the Application, with which you must still comply.