Localization

The SDK string catalog, the runtime locale, the inquiry language pick and the static helpers for text, countries, phone numbers, addresses and dates.

Preview

This page describes a pre-release version of the SDK. Names, versions and APIs on this page can change before the release.

The SDK carries its own string catalog. The SDK's own copy comes from it: the chrome of the inquiry UI in InquiryUiModel.chrome, the failure notice in InquiryUiModel.failure and the error texts the SDK writes itself, so that copy is translated without any string files in your app. The content of an inquiry's steps, such as titles, descriptions and field labels, comes from the inquiry that Folio serves. Your app can read the same catalog through the static helpers on FolioSdk and through the runtime's current locale.

Supported languages

The catalog has eight languages. FolioSdk.availableLocales() returns them in this order:

CodeLanguage
enEnglish
ruRussian
elGreek
esSpanish
frFrench
itItalian
jaJapanese
sqAlbanian

English is the default language. A text that has no translation in a language resolves to its English text.

How a locale string is matched

Every helper that takes a locale accepts a language tag such as fr, fr-CA or fr_CA. The SDK trims it, replaces _ with - and compares it in lower case:

  1. A tag that equals a catalog code uses that language.
  2. Otherwise the primary subtag is used: ru-GE resolves to ru, en-GB to en.
  3. A tag that matches no language, and an empty string, resolve to English.

The runtime locale

The runtime keeps one current locale. It is resolved in this order:

  1. The language the user picked in the inquiry, saved on the device (see below).
  2. The device locale reported by the operating system or the browser.
  3. en.

A blank value counts as missing. FolioSdk.create loads the saved pick before it returns, so the first state of every store is already in the right language. When the saved pick changes, every mounted store publishes its state again, and texts in the new state are in the new language. A change of the device locale while the runtime runs does not make the stores publish again.

The runtime has no member that returns the code of its current locale. Use localizeCurrent for its texts; a helper that takes a locale needs a code your app chooses, such as the device language or one of availableLocales().

localizeCurrent(key) on the runtime returns the text of a TextKey in the current locale:

Swift
let title = try sdk.localizeCurrent(key: .inquiryErrorTitle)

Inside the SDK provider, a view reaches the runtime without passing it down:

On iOS, FolioSDKProvider puts the runtime into the environment as an environment object.

Swift
struct ErrorTitle: View {
    @EnvironmentObject var sdk: FolioSdk

    var body: some View {
        Text((try? sdk.localizeCurrent(key: .inquiryErrorTitle)) ?? "")
    }
}

The inquiry language pick

An inquiry step can contain a language selector. When the user picks a language, the inquiry UI sends InquiryIntent.SetLocale with the chosen locale: .setLocale(locale:) in Swift, InquiryIntent.SetLocale(locale) in Kotlin and InquiryIntent.setLocale(locale) in TypeScript. The SDK:

  1. Saves the pick on the device first.
  2. Sets it as the runtime locale, so every mounted store publishes its state in the new language.
  3. Sends the pick to the inquiry.

If the pick cannot be saved, the intent fails with InquiryError.LocaleNotSaved and a message (.localeNotSaved(message:) in Swift, the type 'LOCALE_NOT_SAVED' in TypeScript). The error is shown as a retryable banner, the locale stays as it was and nothing is sent. See Inquiry store and Errors.

The pick is stored in the device scope, not in the account scope, so it survives sign-out and applies to the next runtime created on the device. See Storage.

The Localizing interface

Localizing is the interface for "localize a key in the current locale". It has one member, which returns the text of key in the runtime's current locale:

PlatformMember
Swiftfunc localizeCurrent(key: TextKey) throws -> String
Kotlinfun localizeCurrent(key: TextKey): String
TypeScriptlocalizeCurrent(key: TextKey): string

FolioSdk implements it. The inquiry UI does not need it: its own copy arrives already localized in the inquiry store's state, in InquiryUiModel.chrome and InquiryUiModel.failure. See Inquiry store.

TextKey

TextKey is the enum of every string in the catalog. Its cases follow the platform naming style:

PlatformExample
Swift.inquiryErrorTitle
KotlinTextKey.INQUIRY_ERROR_TITLE
TypeScriptTextKey.INQUIRY_ERROR_TITLE

In Swift a TextKey has a numeric rawValue and in Kotlin a numeric value. These numbers are not stable between releases: a key can have another number in the next version of the SDK. Refer to a key by its name, and do not store or send its number. In TypeScript a TextKey is its name.

The inquiry store fills InquiryUiModel.chrome from keys such as INQUIRY_ERROR_TITLE, INQUIRY_ERROR_DESCRIPTION, INQUIRY_ERROR_RETRY, INQUIRY_ERROR_CLOSE, INQUIRY_LOADING, INQUIRY_CLEAR_SELECTION and the INQUIRY_NFC_* keys. It fills the failure notice InquiryUiModel.failure from the INQUIRY_ERROR_* keys, from the INQUIRY_LAUNCH_CODE_INVALID_* keys for a launch code that was already used, has expired or is not valid, from the INQUIRY_INVALID_LINK_* keys for another link that was rejected, and from the INQUIRY_CANNOT_RESUME_* keys for a resume that cannot continue. The full list is the TextKey enum in your package.

Static helpers

Stateless helpers are static members of FolioSdk. They need no runtime and can be called before FolioSdk.create, which only sets the host of the flag URLs they return (see Countries and phone numbers). In Swift every helper throws FolioSDKError, and its argument labels are the parameter names. In Kotlin they are @JvmStatic members of the companion object and throw FolioSDKException. In TypeScript they are static methods and throw FolioSDKError. On the web they need the WebAssembly module loaded with initializeFolioWasm first (see Runtime); before that, a call throws a plain Error with the message WASM not initialized, not a FolioSDKError.

Signatures

The Kotlin and TypeScript signatures take the same parameters in the same order as Swift.

SwiftKotlinTypeScript
localize(key: TextKey, locale: String) throws -> Stringlocalize(key: TextKey, locale: String): Stringlocalize(key: TextKey, locale: string): string
localizeWithArgs(key: TextKey, locale: String, args: LocalizeArguments) throws -> StringlocalizeWithArgs(key: TextKey, locale: String, args: LocalizeArguments): StringlocalizeWithArgs(key: TextKey, locale: string, args: LocalizeArguments): string
localizePlural(group: String, count: UInt32, locale: String) throws -> StringlocalizePlural(group: String, count: UInt, locale: String): StringlocalizePlural(group: string, count: number, locale: string): string
localizeCount(group: String, count: UInt32, locale: String) throws -> StringlocalizeCount(group: String, count: UInt, locale: String): StringlocalizeCount(group: string, count: number, locale: string): string
localizeWithCount(key: TextKey, group: String, count: UInt32, locale: String) throws -> StringlocalizeWithCount(key: TextKey, group: String, count: UInt, locale: String): StringlocalizeWithCount(key: TextKey, group: string, count: number, locale: string): string
formatFileSize(bytes: UInt64, locale: String) throws -> StringformatFileSize(bytes: ULong, locale: String): StringformatFileSize(bytes: bigint, locale: string): string
availableLocales() throws -> AvailableLocalesavailableLocales(): AvailableLocalesavailableLocales(): AvailableLocales
countries() throws -> CountryCatalogcountries(): CountryCatalogcountries(): CountryCatalog
country(code: Country) throws -> CountryInfocountry(code: Country): CountryInfocountry(code: Country): CountryInfo
parseCountry(code: String) throws -> Country?parseCountry(code: String): Country?parseCountry(code: string): Country | undefined
countryFlag(country: Country) throws -> CountryFlagcountryFlag(country: Country): CountryFlagcountryFlag(country: Country): CountryFlag
countryByPhone(phone: String) throws -> Country?countryByPhone(phone: String): Country?countryByPhone(phone: string): Country | undefined
phoneDialCode(country: Country) throws -> String?phoneDialCode(country: Country): String?phoneDialCode(country: Country): string | undefined
formatPhoneNational(raw: String, country: Country) throws -> String?formatPhoneNational(raw: String, country: Country): String?formatPhoneNational(raw: string, country: Country): string | undefined
phoneCountryOptions() throws -> [PhoneCountryOption]phoneCountryOptions(): List<PhoneCountryOption>phoneCountryOptions(): PhoneCountryOption[]
subdivisions(country: Country) throws -> SubdivisionCatalogsubdivisions(country: Country): SubdivisionCatalogsubdivisions(country: Country): SubdivisionCatalog
addressForm(address: Address, fallbackCountryCode: String, locale: String) throws -> AddressFormaddressForm(address: Address, fallbackCountryCode: String, locale: String): AddressFormaddressForm(address: Address, fallbackCountryCode: string, locale: string): AddressForm
addressLayout(format: AddressFormat, locale: String) throws -> AddressLayoutaddressLayout(format: AddressFormat, locale: String): AddressLayoutaddressLayout(format: AddressFormat, locale: string): AddressLayout
addressEmpty() throws -> AddressaddressEmpty(): AddressaddressEmpty(): Address
addressDisplay(address: Address) throws -> StringaddressDisplay(address: Address): StringaddressDisplay(address: Address): string
addressChangePart(address: Address, key: AddressKey, value: String) throws -> AddressaddressChangePart(address: Address, key: AddressKey, value: String): AddressaddressChangePart(address: Address, key: AddressKey, value: string): Address
addressChangeCountry(address: Address, country: Country?) throws -> AddressaddressChangeCountry(address: Address, country: Country?): AddressaddressChangeCountry(address: Address, country: Country | undefined): Address
applyDateInputMask(input: String, format: String) throws -> StringapplyDateInputMask(input: String, format: String): StringapplyDateInputMask(input: string, format: string): string
decodeLink(link: String) throws -> LinkRoutedecodeLink(link: String): LinkRoutedecodeLink(link: string): LinkRoute

In Kotlin, a u32 parameter of these functions, such as count, is a UInt and a u64 one is a ULong, while a u32 field of an SDK struct, such as sizeBytes of FileMeta, is a Long.

FolioSdk.mrtdDataGroupsStandard() and FolioSdk.mrtdDataGroupsAll() are static as well; see NFC. So are inquiryTheme(), sdkBuildInfo(), currencies(), iconAsset(icon), statusPalette(), isValidEmail(value), extractRecoveryCode(text), loggingConfig(consoleLevel) and the image helpers barcodeImage, computeMetrics and rotateImage; see Static functions.

Text

HelperReturnsWhat it does
localize(key, locale)StringThe text of key in locale.
localizeWithArgs(key, locale, args)StringThe text of key with its named placeholders filled from args.
localizePlural(group, count, locale)StringThe noun of a plural group in the form that fits count, without the number.
localizeCount(group, count, locale)Stringcount, a space and the noun from localizePlural, for example 1 selected.
localizeWithCount(key, group, count, locale)StringThe text of key with its first placeholder replaced by localizeCount, or by the bare number when group is empty.
formatFileSize(bytes, locale)StringA size such as 512 B or 1.5 MB, with a localized unit.
availableLocales()AvailableLocalesThe catalog languages, see Supported languages.

Placeholders. A catalog text marks a placeholder as ${name}. localizeWithArgs takes LocalizeArguments, whose items is a list of LocalizeArgument with name and value. Each placeholder whose name matches an argument is replaced by its value. A placeholder whose name has a space and whose first word matches an argument is replaced by the value, a space and the rest of the name. A placeholder with no matching argument stays in the text as written.

Plural groups. group is one of DAYS, DOCS, DOCUMENTS, ITEMS, MINUTES, MINUTES_ACCUSATIVE, NIGHTS, PHOTOS, ROOMS, SEC and SELECTED, in any letter case. An unknown group is returned unchanged. Each group has three forms, and the SDK picks one by the count and the language of locale (the part before the first - or _, in any letter case). For Russian (ru), Belarusian (be) and Ukrainian (uk) it picks the first form when the count ends in 1 but not in 11, the second when it ends in 2, 3 or 4 but not in 12, 13 or 14, and the third otherwise. For French (fr) it picks the first form for a count of 0 or 1 and the third otherwise. For Japanese (ja), Chinese (zh) and Korean (ko) it always picks the third form. For every other language it picks the first form for a count of 1 and the third otherwise. Each language's catalog fills these forms with its own words. MINUTES_ACCUSATIVE differs from MINUTES only in Russian, where it has the accusative forms a count takes after a preposition. Pass MINUTES to localizeWithCount: for the two texts that read "try again in N minutes", TextKey.APP_ACC_VERIFY_EMAIL_PLEASE_TRY_AGAIN_IN_N_MINUTES and TextKey.MANUAL_ACC_VERIFY_EMAIL_TOO_MANY_FAILED_ATTEMPTS_PLEASE_TRY_AGAIN_IN_N_MINUTES in Kotlin and TypeScript, the SDK uses MINUTES_ACCUSATIVE on its own.

File sizes. formatFileSize divides by 1024 and uses B, KB, MB or GB. The number is rounded to two decimals and trailing zeros are removed. A size above zero never shows as 0.

AvailableLocales and LocaleInfo:

TypeFieldTypeMeaning
AvailableLocaleslocaleslist of LocaleInfoThe catalog languages
LocaleInfocodeStringThe catalog code, such as fr
LocaleInfonativeNameStringThe language name in its own language
LocaleInfoenglishNameStringThe language name in English

Countries and phone numbers

Country is the shared enum: Country::US in Rust, Country.us in Swift and Country.US in Kotlin and TypeScript. Its 250 values come from ISO 3166-1 plus Kosovo (XK / XKX). JSON uses alpha-2 strings such as "US".

HelperReturnsWhat it does
countries()CountryCatalogAll country metadata records in items, sorted by display name, ignoring letter case and accents.
country(code)CountryInfoMetadata for a typed Country.
parseCountry(code)optional CountryParses alpha-2 or alpha-3 codes, ignoring letter case and surrounding whitespace. Unknown codes return no value.
countryFlag(country)CountryFlagRaster and vector flag URLs for a typed country. See Flag URLs below.
countryByPhone(phone)optional CountryResolves an international phone number using phone metadata, including regions sharing a calling code. Unresolved numbers return no value.
phoneDialCode(country)optional stringThe country's calling code from phonenumber metadata, such as +1 or +49. No value when phone metadata is unavailable.
formatPhoneNational(raw, country)optional stringKeeps the digits of raw and formats them using phone metadata without truncating them. Pass the national number without the trunk prefix (for example without the leading 0 of a French number). Digits that match no format of the country come back as plain digits; missing country metadata returns no value.
phoneCountryOptions()list of PhoneCountryOptionOne option per country that has a calling code, in the order of countries(), by display name. Countries without a calling code are left out.
subdivisions(country)SubdivisionCatalogISO 3166-2 subdivisions with code and name, sorted by name, ignoring letter case and accents. Empty when the country has none in the source library.

A phone selector keeps the selected Country separately from its calling code: both Country.US and Country.CA use +1.

CountryInfo fields:

FieldTypeMeaning
countryCountryThe typed country identifier
alpha2stringISO 3166-1 alpha-2 code
alpha3stringISO 3166-1 alpha-3 code
displayNamestringThe English display name
phoneCodeoptional stringThe calling code
profileoptional CountryProfileProduct metadata, where available

CountryProfile contains denonyms (demonyms), languages, localNames (each with language and name) and addressFormat.

PhoneCountryOption fields:

FieldTypeMeaning
countrystringISO 3166-1 alpha-2 code; pass it to parseCountry for the typed Country
namestringThe English display name, the same as CountryInfo.displayName
dialCodestringThe calling code, such as +49
labelstringThe name, a space and the calling code in parentheses, such as Germany (+49)
flagoptional CountryFlagThe flag URLs, set for every option

phoneCountryOptions() takes no locale, so its names are always English. The inquiry UI's PhoneDialCodeOptionView has the same fields, so one picker component can render both.

Flag URLs. CountryFlag has rasterUrl and vectorUrl, the files https://<domain>/flags/4x3/<code>.png and .svg, where <code> is the alpha-2 code in lowercase. The domain is folio.mobi until FolioSdk.create is first called. Every call with a valid organization sets it from baseUrl for the whole process, even a call that fails later: folio.id, folio.mobi or foliostage.net when the host of baseUrl is that domain or a subdomain of it, and folio.mobi for any other base URL. The latest call wins, and closing a runtime does not reset it. It applies to countryFlag, the flag of phoneCountryOptions() and the flags of the inquiry UI's country and calling code options.

Addresses

The address helpers work on the Address value. Its parts are optional strings: street, city, state, zip, country, apartment, area, neighborhood, townshipOrDistrict, county, furtherDivisions, furtherDivisionsLine2, postalDistrict, suburb, islandName, district and districtOrSubdivision. addressEmpty() returns an address with no parts. In Swift the memberwise initializer takes every part, so start from addressEmpty(). In Kotlin every part defaults to null, so Address() is an empty address. In TypeScript it is a plain object whose type declares every part as string | undefined; an unset part is absent from the object and reads as undefined, so test a part by its value, not with in or Object.keys.

HelperReturnsWhat it does
addressEmpty()AddressAn address with no parts.
addressForm(address, fallbackCountryCode, locale)AddressFormThe form for editing address: the country resolved from address.country, else from fallbackCountryCode, and its rows of fields with their current values and labels in locale.
addressLayout(format, locale)AddressLayoutThe rows of fields for an AddressFormat, such as StrCityCountry, with labels in locale.
addressDisplay(address)StringThe present parts, trimmed, joined by , in the order shown below the table.
addressChangePart(address, key, value)Addressaddress with the part of the AddressKey key set to value. An empty value clears the part.
addressChangeCountry(address, country)Addressaddress with country set to the displayName of the Country, or cleared when country is absent.

addressDisplay writes the parts in this order, whatever the country: street, apartment, area, neighborhood, townshipOrDistrict, county, furtherDivisions, furtherDivisionsLine2, postalDistrict, suburb, islandName, district, districtOrSubdivision, city, state, zip and country. An address with street, city, suburb and county reads as street, county, suburb, city.

addressForm resolves the country from an alpha-2 or alpha-3 code, the ISO name or the display name of a country, in any letter case. AddressForm has countryCode, countryName, rows and display (the same text as addressDisplay). Each row is an AddressFormRow with fields, and each field is an AddressFormField with an AddressKey key, label, value and country, which is true for the country field. The labels of both helpers are catalog texts in locale, matched like every other locale string. AddressLayout has rows of AddressRow, each with fields of AddressFieldSpec, which has an AddressKey key and a label.

In both helpers the row with the Country field always comes first, whatever the format. The other rows follow in the order of the format: the format of the country of the address for addressForm, the given format for addressLayout. For example StrPostalCityCountry gives the rows Country, Street1, Street2, PostalCode and City. When no country resolves, or the country has no address format, addressForm uses the rows of StrCityCountry: Country, Street1, Street2 and City, one per row. When no country resolves, countryCode is empty and countryName is the text it was resolved from.

AddressKey values: Street1, Street2, Area, PostalCode, Postcode, Neighborhood, PrefectureLevelCity, City, TownOrCity, TownshipOrDistrict, CountyOrCity, County, Department, FurtherDivisions, FurtherDivisionsLine2, PostalDistrict, Governorate, Suburb, IslandName, State, Province, Region, SubjectOfFederation, Zip, District, DistrictOrSubdivision, Country and Prefecture. A key reads and writes one part of Address: Street1 the street, Street2 the apartment, the city keys (City, TownOrCity, PrefectureLevelCity, CountyOrCity) the city, the state keys (State, Province, Region, Prefecture, Governorate, SubjectOfFederation, Department) the state, the postal keys (PostalCode, Postcode, Zip) the zip, and every other key the part of the same name.

AddressKey and AddressFormat are spelled by platform:

PlatformAddressKeyAddressFormat
Swift.street1, .postalCode.strCityCountry
KotlinAddressKey.Street1, AddressKey.PostalCodeAddressFormat.StrCityCountry
TypeScript{ type: 'STREET1' }, AddressKey.street1{ type: 'STR_CITY_COUNTRY' }, AddressFormat.strCityCountry

Date and time input

HelperReturnsWhat it does
applyDateInputMask(input, format)StringFormats one keystroke state of a date or time field.

format is a named format, MM_YYYY, DD_MM_YYYY or HH_MM, in any letter case, or a pattern made of dd, mm, yyyy and hh with any separator characters between them, such as dd/mm/yyyy or yyyy-mm-dd. In a pattern, mm right after hh is the minute. The helper keeps only digits, up to the length of the format, and inserts the separators: 122026 becomes 12.2026 and 31122026 becomes 31.12.2026. Time fields use :, so 2359 becomes 23:59. With the pattern dd/mm/yyyy, 31122026 becomes 31/12/2026. A format with any other run of letters, or with no letters at all, returns input unchanged.

The helper corrects impossible values as they are typed:

  • A month above 12, a day above 31, an hour above 23 or a minute above 59 keeps only its first digit with a leading zero: 13 as a month becomes 01, and 2460 becomes 02:06.
  • A month or day of 00 becomes 01.
  • A day past the end of its month becomes the last day of that month: 3104 becomes 30.04 and 30022026 becomes 28.02.2026. Until the year is complete, February allows the 29th.

Calendar values

CalendarDate, CalendarMonth and ClockTime are SDK objects for a calendar date, a month of a year and a time of day, without a time zone. Each has two static constructors: new from its parts and parse from ISO 8601 text.

TypenewValid partsparse accepts
CalendarDatenew(year, month, day)year 0 to 9999, month 1 to 12, day 1 to the last day of the month, so 29 February only in a leap yearYYYY-MM-DD
CalendarMonthnew(year, month)year 0 to 9999, month 1 to 12YYYY-MM
ClockTimenew(hour, minute, second, millisecond)hour 0 to 23, minute and second 0 to 59, millisecond 0 to 999HH:MM, HH:MM:SS, or HH:MM:SS followed by . and 1 to 3 digits of a second; HH:MM means second 0

new never corrects a part: when one is out of range, it throws, as a failed call. parse takes exactly the formats above, with ASCII digits, and throws the same way for any other text or for a value out of range.

The parts are read back with year(), month() and day() on a date, year() and month() on a month, and hour(), minute(), second() and millisecond() on a time. iso8601() returns the text form: YYYY-MM-DD, YYYY-MM, and HH:MM:SS with . and three digits of milliseconds only when the millisecond is not 0.

PlatformParameter and part typesRelease
SwiftUInt16 for year and millisecond, UInt8 for the others; every call throwsrelease(), also on deinit
KotlinUShort for year and millisecond, UByte for the othersclose(), the object is AutoCloseable
TypeScriptnumberdispose() or [Symbol.dispose]()
Swift
let leapDay = try CalendarDate.new(year: 2028, month: 2, day: 29)
let month = try CalendarMonth.parse(value: "2026-10")
let time = try ClockTime.new(hour: 23, minute: 59, second: 0, millisecond: 0)
let text = try time.iso8601()

2028 is a leap year, so leapDay is 29 February 2028, and text is 23:59:00. The same call for 2026 throws, because 2026 is not a leap year: a failed call whose message is the InvalidCalendarValue text "2026-02-29" is not a calendar date.

Instant is an SDK object for a point in time. Its static constructor fromEpochMillis(epochMillis) takes milliseconds since 1970-01-01 UTC, an Int64 in Swift, a Long in Kotlin and a bigint in TypeScript, and throws a failed call with an InvalidCalendarValue message for an instant outside the years 0000 to 9999. epochMillis() returns that number, utc() returns a WallClock, the record of a date (CalendarDate) and a time (ClockTime) in UTC, and iso8601() returns YYYY-MM-DDTHH:MM:SS.mmmZ. Instant is released like the other calendar values.

A date and time value of a field is a DateTimeValue: Absolute { instant }, an Instant, or WallClock { local }, a WallClock without a time zone.

HelperReturnsWhat it does
decodeLink(link)LinkRouteThe route a link asks for. It never throws for a bad link.

decodeLink removes trailing / characters and parses the link. A link whose host is inq, as in <scheme>://inq/<launch code> with any scheme, or a link on a Folio host whose path is /inq/<launch code>, returns LinkRoute.Inquiry with that launchCode. Such a link without a launch code is not an inquiry link. A link that cannot be parsed, or that asks for nothing the SDK knows, returns LinkRoute.Unknown. The cases are spelled .inquiry(launchCode:) and .unknown in Swift, LinkRoute.Inquiry and LinkRoute.Unknown in Kotlin, and have the type 'INQUIRY' and 'UNKNOWN' in TypeScript.

A link with the path /rp/action and an extract query, on a Folio domain such as folio.id or on a Folio link host such as gl-lnk.folio.id, for example https://folio.id/rp/action?extract=IMG_0001.jpeg%3B%3B%3Bscan%20one.pdf, returns LinkRoute.SharedFiles with names, the file names that extract lists: the SDK splits its decoded value at ;;;, trims each name and drops empty ones, so this link gives IMG_0001.jpeg and scan one.pdf. When no name is left, the link returns Unknown. The case is spelled .sharedFiles(names:) in Swift, LinkRoute.SharedFiles(names) in Kotlin and { type: 'SHARED_FILES', value: { names } } in TypeScript, where names is a list of strings.

A link with the content scheme, an Android content URI, returns LinkRoute.Media with that url, whatever its host. The other routes (Entity, Sharing, Interaction, Screen, Preference and External) describe Folio's own links.

Examples

Swift
let french = try FolioSdk.localize(key: .inquiryErrorTitle, locale: "fr")
let languages = try FolioSdk.availableLocales().locales
let countries = try FolioSdk.countries().items
let selected = try FolioSdk.country(code: .us)
let dialCode = try FolioSdk.phoneDialCode(country: .fr)
let national = try FolioSdk.formatPhoneNational(raw: "612345678", country: .fr)
let states = try FolioSdk.subdivisions(country: .us).items
let size = try FolioSdk.formatFileSize(bytes: 1536, locale: "fr")
let expiry = try FolioSdk.applyDateInputMask(input: "122026", format: "MM_YYYY")
let empty = try FolioSdk.addressEmpty()
let located = try FolioSdk.addressChangeCountry(address: empty, country: .fr)
let address = try FolioSdk.addressChangePart(address: located, key: .city, value: "Paris")
let form = try FolioSdk.addressForm(address: address, fallbackCountryCode: "FR", locale: "fr")

On this page