[Huawei Developers] muraliameakula:
Article Introduction

In this article, we will show how to integrate Huawei ML Kit (Real-time Language Detection and Real-time Language Translation) in iOS using native language (Swift). The use case has been created to make Smart Translator supporting more than 38 languages with HMS open capabilities.

Huawei ML Kit (Real-time Language Detection)

The real-time language detection service can detect the language of text. Both single-language text and multi-language text are supported. ML Kit detects languages in text and returns the language codes (the BCP-47 standard is used for Traditional Chinese, and the ISO 639-1 standard is used for other languages) and their respective confidences or the language code with the highest confidence. Currently, the real-time language detection service supports 109 languages.

Huawei ML Kit (Real-time Language Translation)

The real-time translation service can translate text from the source language into the target language through the server on the cloud. Currently, real-time translation supports 38 languages.

For this article, we implemented cloud based real-time Language Detection and real-time Language Translation for iOS with native Swift language.

Pre-Requisites

Before getting started, following are the requirements:

Xcode (During this tutorial, we used latest version 12.4)

iOS 9.0 or later (ML Kit supports iOS 9.0 and above)

Apple Developer Account

iOS device for testing

Development

Following are the major steps of development for this article:

Step 1: Importing the SDK in Pod Mode.

1.1: Check whether Cocoapods has been installed:

gem -v

If not, run the following commands to install Cocoapods:

sudo gem install cocoapods
pod setup

1.2: Run the pod init command in the root directory of the Xcode project and add the current version number to the generated Podfile file.

pod "ViewAnimator" # ViewAnimator for cool animations
pod 'lottie-ios' # Lottie for Animation
pod 'MLTranslate', '~>2.0.5.300' # Real-time translation
pod 'MLLangDetection', '~>2.0.5.300' # Real-Time Language Detection

1.3: Run the following command in the same directory of the Podfile file to integrate the HMS Core Scan SDK:

pod install

If you have used Cocoapods, run the following command to update Cocoapods:

pod update

1.4: After the execution is successful, open the project directory, find the .xcworkspace file, and execute it.

Step 2: Generating Supported Language JSON.

Since our main goal is Smart Translator, we restricted real-time language detection to 38 languages and generated a JSON file locally to avoid API creation and API calling. In real world scenario, an API can be developed or Huawei ML Kit can be used to get all the supported languages.

Step 3: Building Layout.

We used Auto Layout. Auto Layout defines your user interface using a series of constraints. Constraints typically represent a relationship between two views. Auto Layout then calculates the size and location of each view based on these constraints. This produces layouts that dynamically respond to both internal and external changes.

In this article, we also used Lottie animation for splash animation and for the loading animation when user translate anything. We also used ViewAnimator library to load History UITableView items.

func showAppIntro(){
DispatchQueue.main.async {
self.animationView.animation = Animation.named("intro_animation")
self.animationView.contentMode = .scaleAspectFit
self.animationView.play(fromFrame: AnimationFrameTime.init(30), toFrame: AnimationFrameTime.init(256), loopMode: .playOnce) { (completed) in
// Let's open Other Screen once the animation is completed
self.performSegue(withIdentifier: "goToServiceIntro", sender: nil)
}
}
}

func showLoader(){
DispatchQueue.main.async {
self.animationView.isHidden = false
self.animationLoader.play()
}
}

func hideLoader(){
DispatchQueue.main.async {
self.animationView.isHidden = true
self.animationLoader.stop()
}
}

func loadAnimateTableView(){
let fromAnimation = AnimationType.vector(CGVector(dx: 30, dy: 0))
let zoomAnimation = AnimationType.zoom(scale: 0.2)

self.historyList.append(contentsOf: AppUtils.getTranslationHistory())
self.historyTableView.reloadData()

UIView.animate(views: self.historyTableView.visibleCells,
animations: [fromAnimation, zoomAnimation], delay: 0.5)
}

Step 4: Integrating ML Kit

By default, Auto is selected which will detect the entered language using ML Kit Real-time Language Detection APIs. User can also swap the languages if auto is not selected. Once user enter the text and press enter, the ML Kit Real-time Language Translation APIs are called and display the result in the other box.

// This extension is responsible for MLLangDetect and MLTranslate related functions
extension HomeViewController {
func autoDetectLanguage(enteredText: String){
if enteredText.count > 1 {
self.txtLblResult.text = "" // Reset the translated text
self.showLoader()
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.mlRemoteLangDetect?.syncFirstBestDetect(enteredText, addOnSuccessListener: { (lang) in
// Get the Language that user entered, incase unable to identify, please change auto to your language
let detectedLanguage = AppUtils.getSelectedLanguage(langCode: lang)

if detectedLanguage == nil {
self.hideLoader()
self.displayResponse(message: "Oops! We are not able to detect your language 🧐 Please select your language from the list for better results 😉")
return // No Need to run the remaining code
}

self.langFrom = detectedLanguage!

// Once we detect the language, let's add Auto suffix to let user know that it's automatically detected
let langName = "\(String(describing: self.langFrom!.langName)) - Auto"
self.langFrom!.langName = langName

// Let's update the buttons titles
self.setButtonsTitle()

// Let's do the translation now
self.translateText(enteredText: enteredText)
}, addOnFilureListener: { (exception) in
self.hideLoader()
self.displayResponse(message: "Oops! We are unable to process your request at the moment 😞")
})
}
}
}

func translateText(enteredText: String){
// Let's Init the translator with selected languages
self.initLangTranslate()
if enteredText.count > 1 {
self.txtLblResult.text = "" // Reset the translated text
self.showLoader()
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
MLRemoteTranslator.sharedInstance().syncTranslate(enteredText) { (translatedText) in
self.txtLblResult.text = translatedText
self.saveTranslationHistory() // This function will save translation history
self.hideLoader()
} addOnFailureListener: { (exception) in
self.hideLoader()
self.displayResponse(message: "Oops! We are unable to process your request at the moment 😞")
}
}
} else {
self.hideLoader()
self.displayResponse(message: "Please write something 🧐")
}
}

func saveTranslationHistory(){
AppUtils.saveData(fromText: edtTxtMessage.text!, toText: txtLblResult.text!, fromLang: self.langFrom!.langName, toLang: self.langTo!.langName)
}
}

Step 5: Save translation History locally on the device.

After getting the result, we call helper functions to save data and retrieve it using NSUserDefault when needed. We also provide an option to delete all data in the History Screen.

static func saveData(fromText: String, toText: String, fromLang: String, toLang: String){
var history = self.getTranslationHistory()

history.insert(TranslationHistoryModel.init(dateTime: getCurrentDateTime(), fromText: fromText, toText: toText, fromLang: fromLang, toLang: toLang), at: 0)

do {
let encodedData = try NSKeyedArchiver.archivedData(withRootObject: history, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "TranslationHistory")
UserDefaults.standard.synchronize()
} catch {
print(error)
}
}

static func clearHistory(){
let history: [TranslationHistoryModel] = []
do {
let encodedData = try NSKeyedArchiver.archivedData(withRootObject: history, requiringSecureCoding: false)
UserDefaults.standard.set(encodedData, forKey: "TranslationHistory")
UserDefaults.standard.synchronize()
} catch {
print(error)
}
}

static func getTranslationHistory() -> [TranslationHistoryModel]{
let decoded = UserDefaults.standard.data(forKey: "TranslationHistory")
if decoded != nil {
do {
let result = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decoded!) as? [TranslationHistoryModel]
if result != nil {
return result!
} else {
return []
}
} catch {
print(error)
return []
}
} else {
return []
}
}

Step 6: Displaying History in UITableView.

We then add all the items in UITableView

// This extension is responsible for UITableView related things
extension HistoryViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.historyList.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HistoryTableViewCell", for: indexPath) as! HistoryTableViewCell

let entity: TranslationHistoryModel = self.historyList[indexPath.row]

cell.txtLblFrom.text = entity.fromLang
cell.txtLblFromText.text = entity.fromText
cell.txtLblTo.text = entity.toLang
cell.txtLblToText.text = entity.toText
cell.txtDateTime.text = entity.dateTime
cell.index = indexPath.row

cell.setCellBackground()

return cell
}
}

Step 7: Initiate MLTranslate and MLLangDetect with API KEY.

This is very important step. We have to add the following line of code in the AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

// Setting API key so that we can use ML Kit for translation
MLTranslateApplication.sharedInstance().setApiKey(AppUtils.API_KEY)
MLLangDetectApplication.sharedInstance().setApiKey(AppUtils.API_KEY)

return true
}

Step 8: Run the application.

We have added all the required code. Now, just build the project, run the application and test on any iOS phone. In this demo, we used iPhone 11 Pro Max for testing purposes.

Conclusion

Whenever user travel to a new place, country or region, he can use this app to translate text from their native language to the visited place spoken language. Once they are done with translation, they can also check the translated history or show it to someone so that they can communicate with the locals easily and conveniently with Smart Translator.

Using ML Kit, developers can develop different iOS applications with auto detect option to improve the UI/UX. ML Kit is a on-device and on-cloud open capability offered by Huawei which can be combined with other functionalities to offer innovative services to the end users.

Tips and Tricks

Before calling the ML Kit, make sure the required agconnect-services.plist is added to the project and ML Kit APIs are enabled from the AGConnect console.

ML Kit must be initiated with the API Key in the AppDelegate.swift.

There are no special permissions needed for this app. However, make sure that the device is connected to Internet and have active connection.

Always use animation libraries like Lottie or ViewAnimator to enhance UI/UX in your application.

References

Huawei ML Kit Official Documentation: click here

Huawei ML Kit FAQs: click here

Lottie iOS Documentation: click here

Github Code Link: click here

Original Source