Skip to content

Commit

Permalink
Add SDK support for string substitution.
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardbeecroft committed May 25, 2023
1 parent 894ebec commit 4898df4
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"location" : "git@github.com:QuickVerse/quickverse-ios-sdk.git",
"state" : {
"branch" : "main",
"revision" : "9795b61f5da02b1552195c32c921697ade5e7356"
"revision" : "894ebec47e66de7b31afdc814a78098edc2a5888"
}
}
],
Expand Down
1 change: 1 addition & 0 deletions Examples/Shared/QVKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ import Foundation

class QVKey {
static let onboardingDemoTitle = "Onboarding.Demo.Title"
static let onboardingDemoTitleWithUser = "Onboarding.Demo.TitleWithUser"
static let onboardingDemoBody = "Onboarding.Demo.Body"
}
7 changes: 0 additions & 7 deletions Examples/SwiftUI-Example/Components/FilledButton.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
//
// FilledButton.swift
// SwiftUI-Example
//
// Created by Ed Beecroft on 06/05/2023.
//

import SwiftUI

struct FilledButton: View {
Expand Down
16 changes: 13 additions & 3 deletions Examples/SwiftUI-Example/ContentViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,22 @@ class ContentViewModel: ObservableObject {
}
}
private func updateLocalizedText() {
// Access values using the keys you declared in your quickverse.io account
titleText = QuickVerse.stringFor(key: "Onboarding.Demo.Title")

// Strongly Recommended - Use a centrally-declared keys file, such as QVKey - seen here
titleText = QuickVerse.stringFor(key: QVKey.onboardingDemoTitle)
// Alternatively, keys can be hardcoded "inline"
bodyText = QuickVerse.stringFor(key: QVKey.onboardingDemoBody)

// Optionally use our compact accessor "QV"
titleText = QV.stringFor(key: QVKey.onboardingDemoTitle)

// Optionally provide a default value
titleText = QuickVerse.stringFor(key: QVKey.onboardingDemoTitle, defaultValue: "Welcome to QuickVerse!")
titleText = QV.stringFor(key: QVKey.onboardingDemoTitle, defaultValue: "Welcome to QuickVerse!")

// Optionally provide a substitution
titleText = QV.stringFor(key: QVKey.onboardingDemoTitleWithUser,
substitutions: [QVSubstitution(replace: "%@", with: "Alice")])

bodyText = QV.stringFor(key: QVKey.onboardingDemoBody)
}
}
16 changes: 13 additions & 3 deletions Examples/UIKit-Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,23 @@ private extension ViewController {
}
}
func updateLocalizedText() {
// Access values using the keys you declared in your quickverse.io account
onboardingTitleLabel.text = QuickVerse.stringFor(key: "Onboarding.Demo.Title")

// Strongly Recommended - Use a centrally-declared keys file, such as QVKey - seen here
onboardingTitleLabel.text = QuickVerse.stringFor(key: QVKey.onboardingDemoTitle)
// Alternatively, keys can be hardcoded "inline"
onboardingBodyLabel.text = QuickVerse.stringFor(key: "Onboarding.Demo.Body")

// Optionally use our compact accessor "QV"
onboardingTitleLabel.text = QV.stringFor(key: QVKey.onboardingDemoTitle)

// Optionally provide a default value
onboardingTitleLabel.text = QuickVerse.stringFor(key: QVKey.onboardingDemoTitle, defaultValue: "Welcome to QuickVerse!")
onboardingTitleLabel.text = QV.stringFor(key: QVKey.onboardingDemoTitle, defaultValue: "Welcome to QuickVerse!")

// Optionally provide a substitution
onboardingTitleLabel.text = QV.stringFor(key: QVKey.onboardingDemoTitleWithUser,
substitutions: [QVSubstitution(replace: "%@", with: "Alice")])

onboardingBodyLabel.text = QV.stringFor(key: QVKey.onboardingDemoBody)
}
}

Expand Down
2 changes: 1 addition & 1 deletion QuickVerse.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = "QuickVerse"
spec.version = "1.4.3"
spec.version = "1.4.4"
spec.summary = "Effortlessly integrate your quickverse.io localisations into your iOS app, for instant, over-the-air updates & more."
spec.description = <<-DESC
QuickVerse lets you translate your web and mobile apps with ease. Powered by instant, over-the-air updates, you can change your app copy anytime, anywhere.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![Version](https://img.shields.io/static/v1?label=pod&message=1.4.3&color=blue&style=flat)](#cocoapods)
[![Version](https://img.shields.io/static/v1?label=pod&message=1.4.4&color=blue&style=flat)](#cocoapods)
[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-success.svg?style=flat)](#Swift-Package-Manager)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-success.svg?style=flat)](#carthage)
[![Twitter](https://img.shields.io/twitter/follow/quickverse_io?style=social)](https://twitter.com/quickverse_io)
Expand Down Expand Up @@ -36,7 +36,7 @@ The library should have been added to the Swift Package Dependencies section, an

```
pod 'QuickVerse' // Always use the latest version
pod 'QuickVerse', '~> 1.4.3' // Or pin to a specific version
pod 'QuickVerse', '~> 1.4.4' // Or pin to a specific version
```
2. In a terminal window, navigate to the directory of your `Podfile`, and run `pod install --repo-update`

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extension String {
func lowercasingFirstLetter() -> String {
return prefix(1).lowercased() + self.dropFirst()
}
}
11 changes: 8 additions & 3 deletions Sources/QuickVerse/Internal/Managers/LoggingManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ struct LoggingManager {
static func logCodeForAvailableLocalizations(_ localizations: [QuickVerseLocalization]) {
var casesString = ""
for (index, localization) in localizations.enumerated() {
let propertyName = localization.key.replacingOccurrences(of: ".", with: "_")
casesString.append("static let \(propertyName) = \"\(localization.key)\"")
casesString.append("static let \(clean(key: localization.key)) = \"\(localization.key)\"")
if index != localizations.count - 1 {
casesString.append("\n\t")
}
Expand All @@ -20,10 +19,16 @@ struct LoggingManager {
\(casesString)
}
Example: QuickVerse.stringFor(key: QVKey.\(localizations.last?.key.replacingOccurrences(of: " .,-", with: "", options: [.regularExpression]) ?? ""))
Example: QuickVerse.stringFor(key: QVKey.\(clean(key: localizations.last?.key ?? "")))
ℹ️ℹ️ℹ️ DEBUG: END AVAILABLE LOCALIZATION KEYS ℹ️ℹ️ℹ️
"""
LoggingManager.log(logString)
}
// Removes characters from the key to provide a property name that Xcode will accept.
private static func clean(key: String) -> String {
return key
.replacingOccurrences(of: "[ ._,-]", with: "", options: .regularExpression)
.lowercasingFirstLetter()
}
}
2 changes: 1 addition & 1 deletion Sources/QuickVerse/Internal/Networking/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ protocol API {

class APIClient: API {
var apiKey: String!
private let sdkVersion = "1.4.3"
private let sdkVersion = "1.4.4"

private let session: URLSession
init(session: URLSession) {
Expand Down
18 changes: 11 additions & 7 deletions Sources/QuickVerse/Public/QuickVerseManager.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

/// Convenience global accessors, allowing you to call QuickVerse methods with shorter footprint, for example: QuickVerse.getLocalizations(, or QV.getLocalizations(,
/// Compact global accessors, allowing you to call QuickVerse methods with shorter footprint, for example: QuickVerse.getLocalizations(, or QV.getLocalizations(
public let QuickVerse = QuickVerseManager.shared
public let QV = QuickVerseManager.shared

Expand Down Expand Up @@ -54,14 +54,14 @@ You can call these from anywhere in your app, e.g. Quickverse.stringFor(key: "On
*/
extension QuickVerseManager {
/// Returns the value for a specific key, falling back to a default value
public func stringFor(key: String, defaultValue: String) -> String {
public func stringFor(key: String, defaultValue: String, substitutions: [QVSubstitution]? = nil) -> String {
logRequestedKey(key, defaultValue: defaultValue)
return getValueFor(key: key) ?? defaultValue
return getValueFor(key: key, substitutions: substitutions) ?? defaultValue
}
/// Returns the value for a specific key, or null if one does not exist
public func stringFor(key: String) -> String? {
public func stringFor(key: String, substitutions: [QVSubstitution]? = nil) -> String? {
logRequestedKey(key, defaultValue: "")
return getValueFor(key: key)
return getValueFor(key: key, substitutions: substitutions)
}
}

Expand Down Expand Up @@ -109,8 +109,12 @@ private extension QuickVerseManager {
}
}
}
func getValueFor(key: String) -> String? {
return localizations.first(where: { $0.key == key })?.value
func getValueFor(key: String, substitutions: [QVSubstitution]?) -> String? {
var value = localizations.first(where: { $0.key == key })?.value
substitutions?.forEach {
value = value?.replacingOccurrences(of: $0.replace, with: $0.with)
}
return value
}
}

Expand Down
9 changes: 9 additions & 0 deletions Sources/QuickVerse/Public/QuickVerseSubstitution.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public struct QVSubstitution {
public let replace: String
public let with: String

public init(replace: String, with: String) {
self.replace = replace
self.with = with
}
}

0 comments on commit 4898df4

Please sign in to comment.