You can use ML Kit to translate text between languages. ML Kit
can translation between more than
[50 languages](https://developers.google.com/ml-kit/languages/translation/translation-language-support).

<br />

> [!NOTE]
> **Note:** ML Kit iOS APIs only run on 64-bit devices. If you build your app with 32-bit support, check the device's architecture before using this API.

## Try it out

- Play around with [the sample app](https://github.com/googlesamples/mlkit/tree/master/ios/quickstarts/translate) to see an example usage of this API.

## Before you begin

1. Include the following ML Kit pods in your Podfile:

   ```
   pod 'GoogleMLKit/Translate', '8.0.0'
   ```
2. After you install or update your project's Pods, open your Xcode project using its `.xcworkspace`. ML Kit is supported in Xcode version 12.4 or greater.

## Translate a string of text

To translate a string between two languages:

1. Create a `Translator` object, configuring it with the source and target
   languages:

   ### Swift

   ```swift
       // Create an English-German translator:
       let options = TranslatorOptions(sourceLanguage: .english, targetLanguage: .german)
       let englishGermanTranslator = Translator.translator(options: options)
   ```

   ### Objective-C

   ```objective-c
       // Create an English-German translator:
       MLKTranslatorOptions *options =
           [[MLKTranslatorOptions alloc] initWithSourceLanguage:MLKTranslateLanguageEnglish
                                                 targetLanguage:MLKTranslateLanguageGerman];
       MLKTranslator *englishGermanTranslator =
           [MLKTranslator translatorwithOptions:options];
   ```

   If you don't know the language of the input text, you can use the [Language
   Identification API](https://developers.google.com/ml-kit/languages/identification) which
   gives you a language tag. Then convert the language tag to
   an ML Kit enum. The code depends on which language you're using:
   - Swift: Call [`TranslateLanguage.fromLanguageTag()`]() to get a [`TranslateLanguage`]()
   - Objective-C: Call [`MLKTranslateLanguageForLanguageTag()`]() to get an [`MLKTranslateLanguage`]()

   Avoid keeping too many language models on the device at once.
2. Make sure the required translation model has been downloaded to the device.
   Don't call `translate(_:completion:)` until you know the model is available.

   ### Swift

   ```swift
   let conditions = ModelDownloadConditions(
       allowsCellularAccess: false,
       allowsBackgroundDownloading: true
   )
   englishGermanTranslator.downloadModelIfNeeded(with: conditions) { error in
       guard error == nil else { return }

       // Model downloaded successfully. Okay to start translating.
   }
   ```

   ### Objective-C

   ```objective-c
   MLKModelDownloadConditions *conditions =
       [[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:NO
                                            allowsBackgroundDownloading:YES];
   [englishGermanTranslator downloadModelIfNeededWithConditions:conditions
                                                     completion:^(NSError *_Nullable error) {
     if (error != nil) {
       return;
     }
     // Model downloaded successfully. Okay to start translating.
   }];
   ```

   Language models are around 30MB, so don't download them unnecessarily, and
   only download them using Wi-Fi unless the user has specified otherwise. You
   should delete models when they are no longer needed.
   See [Explicitly manage translation models](https://developers.google.com/ml-kit/language/translation/ios.md.txt#manage-models).
3. After you confirm the model has been downloaded, pass a string of text in
   the source language to `translate(_:completion:)`:

   ### Swift

   ```swift
         englishGermanTranslator.translate(text) { translatedText, error in
             guard error == nil, let translatedText = translatedText else { return }

             // Translation succeeded.
         }
   ```

   ### Objective-C

   ```objective-c
         [englishGermanTranslator translateText:text
                                     completion:^(NSString *_Nullable translatedText,
                                                  NSError *_Nullable error) {
           if (error != nil || translatedText == nil) {
             return;
           }

           // Translation succeeded.
         }];
   ```

   ML Kit translates the text to the target language you configured and
   passes the translated text to the completion handler.

> Translator lifecycles are controlled by ARC (automatic reference counting),
> which is the recommended convention for iOS development. Developers can expect
> the Translator to be deallocated once all strong references have been removed.
>
> Translators can occupy 30MB-150MB when loaded in memory. Developers should
> keep the memory budget of the device/app in mind when creating concurrent
> translator instances and avoid keeping too many language models on the device
> at once.

## Explicitly manage translation models


When you use the translation API as described above, ML Kit automatically
downloads language-specific translation models to the device as required. You
can also explicitly manage the translation models you want available on the
device by using ML Kit's translation model management API. This can be
useful if you want to download models ahead of time, or delete unneeded models
from the device.

<br />

To get the translation models stored on the device:

### Swift

```swift
let localModels = ModelManager.modelManager().downloadedTranslateModels
```

### Objective-C

```objective-c
NSSet *localModels =
    [MLKModelManager modelManager].downloadedTranslateModels;
```

To delete a model:

### Swift

```swift
// Delete the German model if it's on the device.
let germanModel = TranslateRemoteModel.translateRemoteModel(language: .german)
ModelManager.modelManager().deleteDownloadedModel(germanModel) { error in
    guard error == nil else { return }
    // Model deleted.
}
```

### Objective-C

```objective-c
// Delete the German model if it's on the device.
MLKTranslateRemoteModel *germanModel =
    [MLKTranslateRemoteModel translateRemoteModelWithLanguage:MLKTranslateLanguageGerman];
[[MLKModelManager modelManager] deleteDownloadedModel:germanModel
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   return;
                                               }
                                               // Model deleted.
```

To download a model:

### Swift

```swift
// Download the French model.
let frenchModel = TranslateRemoteModel.translateRemoteModel(language: .french)

// Keep a reference to the download progress so you can check that the model
// is available before you use it.
progress = ModelManager.modelManager().download(
    frenchModel,
    conditions: ModelDownloadConditions(
        allowsCellularAccess: false,
        allowsBackgroundDownloading: true
    )
)
```

If you want to get the download status with `NotificationCenter`, register
observers for `mlkitModelDownloadDidSucceed` and
`mlkitModelDownloadDidFail`. Be sure to use a weak reference to `self`
in the observer block, since downloads can take some time, and the originating
object can be freed by the time the download finishes. For example:

```swift
NotificationCenter.default.addObserver(
    forName: .mlkitModelDownloadDidSucceed,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? TranslateRemoteModel,
        model == frenchModel
        else { return }
    // The model was downloaded and is available on the device
}

NotificationCenter.default.addObserver(
    forName: .mlkitModelDownloadDidFail,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? TranslateRemoteModel
        else { return }
    let error = userInfo[ModelDownloadUserInfoKey.error.rawValue]
    // ...
}
```

### Objective-C

```objective-c
// Download the French model.
MLKModelDownloadConditions *conditions =
    [[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:NO
                                         allowsBackgroundDownloading:YES];
MLKTranslateRemoteModel *frenchModel =
    [MLKTranslateRemoteModel translateRemoteModelWithLanguage:MLKTranslateLanguageFrench];

// Keep a reference to the download progress so you can check that the model
// is available before you use it.
self.downloadProgress = [[MLKModelManager modelManager] downloadModel:frenchModel
conditions:conditions];
```

If you want to get the download status with `NSNotificationCenter`, register
observers for `MLKModelDownloadDidSucceedNotification` and
`MLKModelDownloadDidFailNotification`. Be sure to use a weak reference to
`self` in the observer block, since downloads can take some time, and the
originating object can be freed by the time the download finishes.

```objective-c
__block MyViewController *weakSelf = self;

[NSNotificationCenter.defaultCenter
 addObserverForName:MLKModelDownloadDidSucceedNotification
 object:nil
 queue:nil
 usingBlock:^(NSNotification * _Nonnull note) {
     if (weakSelf == nil | note.userInfo == nil) {
         return;
     }

     MLKTranslateRemoteModel *model = note.userInfo[MLKModelDownloadUserInfoKeyRemoteModel];
     if ([model isKindOfClass:[MLKTranslateRemoteModel class]]
         && model == frenchModel) {
         // The model was downloaded and is available on the device
     }
 }];

[NSNotificationCenter.defaultCenter
 addObserverForName:MLKModelDownloadDidFailNotification
 object:nil
 queue:nil
 usingBlock:^(NSNotification * _Nonnull note) {
     if (weakSelf == nil | note.userInfo == nil) {
         return;
     }

     NSError *error = note.userInfo[MLKModelDownloadUserInfoKeyError];
 }];
```