昨天接到幾個新任務, 第一個是要實現文字翻譯功能. 從網上搜尋資料發現常用的有百度翻譯, 有道翻譯 , Google翻譯.
三者盡心對比: 1. 百度每月200萬字元下免費
2. 有道收費,初始送100元體驗金
3.Google翻譯純英文文檔.
綜合考慮, 百度翻譯免費,支援語言更多,決定使用百度翻譯.
前期準備大致相同,註冊帳號,申請APPID和密鑰. 一個帳號只能申請一個ID, 如果你有多個APP 那就需要多個帳號進行申請.
前期準備略過,看文檔就可以了.
文檔不多,並且沒有oc版本.
百度提供了介面進行網路請求,返回翻譯結果. 文檔中說可以用get也可以post,我使用的是get.
介面中必須要寫入的參數:
q:待翻譯的文本;
from: 待翻譯文本語言
to: 目標語言
APPID: 申請的APPID
salt: 隨機數, 文檔中沒有詳細說這個,我從網上其他人的部落格中看到可以使用文檔中提供的隨機數,猜測可能是只要長度為10位的數字都可以,但是我並沒有去驗證,仍是使用的文檔提供的隨隨機數.
sign: 簽名; 按照文檔,將APPID,q,salt,密鑰 拼接, 之後進行utf-8編碼,然後MD5加密,得到簽名.
待翻譯文字需要utf-8編碼,是因為如果待翻譯的文字是中文,網路請求並不支援中文,需要將文字進行utf-8編碼.
但是在我按照文檔進行時,出現了幾個問題:
1.只能翻譯單個英文單詞,不能翻譯英文句子.
2.無法將中文翻譯成英文.
錯誤碼是 54001: sign(簽名)錯誤.
我在這裡卡了很長時間,完全不知道錯誤出在哪裡.
在參考完一篇部落格之後,我找到了問題所在.
文檔中是這樣描述簽名產生的:"計算簽名sign(對字串1做md5加密,注意計算md5之前,串1必須為UTF-8編碼)"
但是這一句話並不是完全正確的.
這裡的 字串1 是將APPID,q,salt,密鑰 拼接起來的結果, 按照文檔接下來是進行utf-8編碼,然後MD5加密.
最重要的:
編碼: 在iOS9之前我們使用stringByAddingPercentEscapesUsingEncoding 進行utf-8編碼,但是此方法在iOS10中被廢棄了.所以你會使用哪個方法來編碼呢?
如果你使用舊的方法進行編碼,問題就解決了, 我上面遇到的兩個問題都解決了.
如果你使用新的方法進行編碼,不好意思,你就會遇到我遇到的問題.
那我們只能使用舊方法了嗎,畢竟已經是被廢棄了.
然後我試了試一種情況,發現這樣也可以. 那就是: 字串1不進行utf-8編碼,直接進行加密, 當然請求時的utf-8編碼還是必須的. 這樣操作之後,問題解決了.
所以,拼接之後,完全不用utf-8編碼,直接加密就可以了. 即使你的待翻譯文字是中文.
這次功能主要參考了兩篇部落格,非常感謝. 部落格中有什麼不對的地方,請不吝賜教.
點擊開啟連結
點擊開啟連結
以下是完整的請求代碼:
_inputText = _inputTextView.text;// _inputText = @"今天 是個 好天氣"; //百度API NSString *httpStr = @"https://fanyi-api.baidu.com/api/trans/vip/translate"; //將APPID q salt key 拼接一起 NSString *appendStr = [NSString stringWithFormat:@"%@%@%@%@",kBaiduTranslationAPPID,_inputText,kBaiduTranslationSalt,kBaiduTranslationKey]; //將拼接之後的字串進行utf-8轉碼 //[appendStr stringByRemovingPercentEncoding:[NSCharacterSet URLQueryAllowedCharacterSet]]; // NSString *appendEncoding = [appendStr stringByRemovingPercentEncoding]; // NSString *appendEncoding = [appendStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];// NSLog(@"&&&&&&&%@",appendStr); //加密 產生簽名 NSString *md5Str = [self md5:appendEncoding]; //將待翻譯的文字機型urf-8轉碼 NSString *qEncoding = [_inputText stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; //使用get請求 NSString *urlStr = [NSString stringWithFormat:@"%@?q=%@&from=%@&to=%@&appid=%@&salt=%@&sign=%@",httpStr,qEncoding,@"auto",@"en",kBaiduTranslationAPPID,kBaiduTranslationSalt,md5Str]; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //添加共有參數 [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"]; manager.requestSerializer.timeoutInterval = 20.f; [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"]; [manager GET:urlStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if (responseObject == nil) { return ; } //擷取翻譯後的字串 NSString *resStr = [[responseObject objectForKey:@"trans_result"] firstObject][@"dst"]; self.outputTextView.text = resStr; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }];