Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ SPEC CHECKSUMS:
Nocilla: ae0a2b05f3087b473624ac2b25903695df51246a
Polyglot: 9357934dadad89a6d68fc6f82047677349bce3df

COCOAPODS: 0.39.0
COCOAPODS: 0.38.2
50 changes: 24 additions & 26 deletions Polyglot/Polyglot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import Foundation

/**
Supported languages.
*/
Supported languages.
*/
public enum Language: String {
case Arabic = "ar"
case Bosnian = "bs"
Expand Down Expand Up @@ -117,33 +117,34 @@ public enum Language: String {
/**
Responsible for translating text.
*/
public class Polyglot {
open class Polyglot {

let session: Session

/// The language to be translated from. It will automatically detect the language if you do not set this.
public var fromLanguage: Language?
open var fromLanguage: Language?

/// The language to translate to.
public var toLanguage: Language
open var toLanguage: Language


/**
- parameter clientId: Microsoft Translator client ID.
- parameter clientSecret: Microsoft Translator client secret.
*/
- parameter clientId: Microsoft Translator client ID.
- parameter clientSecret: Microsoft Translator client secret.
*/
public init(clientId: String, clientSecret: String) {
session = Session(clientId: clientId, clientSecret: clientSecret)
toLanguage = Language.English
}

/**
Translates a given piece of text.
Translates a given piece of text asynchronously. Switch to the main thread within the callback
if you want to update your UI by using `dispatch_async(dispatch_get_main_queue()) { /* code */ }`.

- parameter text: The text to translate.
- parameter callback: The code to be executed once the translation has completed.
*/
public func translate(text: String, callback: ((translation: String) -> (Void))) {
public func translate(text: String, callback: @escaping ((_ translation: String?, _ error: Error?) -> (Void))) {
session.getAccessToken { token in
if self.fromLanguage == nil {
self.fromLanguage = text.language
Expand All @@ -152,34 +153,31 @@ public class Polyglot {
let fromLanguageComponent = (self.fromLanguage != nil) ? "&from=\(self.fromLanguage!.rawValue.urlEncoded!)" : ""
let urlString = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=\(text.urlEncoded!)\(toLanguageComponent)\(fromLanguageComponent)"

let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "GET"
var request = URLRequest(url: URL(string: urlString)!)
request.httpMethod = "GET"
request.setValue("Bearer " + token, forHTTPHeaderField: "Authorization")

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {(data, response, error) in
let translation: String
let task = URLSession.shared.dataTask(with: request, completionHandler: {(data, response, error) in
let translation : String?
guard
let data = data,
let xmlString = NSString(data: data, encoding: NSUTF8StringEncoding) as? String
let xmlString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as String?
else {
translation = ""
return
}

translation = self.translationFromXML(xmlString)

defer {
dispatch_async(dispatch_get_main_queue()) {
callback(translation: translation)
DispatchQueue.main.async {
callback(translation, error)
}
}
}
})
task.resume()
}
}

private func translationFromXML(XML: String) -> String {
let translation = XML.stringByReplacingOccurrencesOfString("<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">", withString: "")
return translation.stringByReplacingOccurrencesOfString("</string>", withString: "")
fileprivate func translationFromXML(_ XML: String) -> String {
let translation = XML.replacingOccurrences(of: "<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">", with: "")
return translation.replacingOccurrences(of: "</string>", with: "")
}
}
34 changes: 17 additions & 17 deletions Polyglot/Session.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,47 +28,47 @@ class Session {
let clientSecret: String

var accessToken: String?
var expirationTime: NSDate?
var expirationTime: Date?

init(clientId: String, clientSecret: String) {
self.clientId = clientId
self.clientSecret = clientSecret
}

func getAccessToken(callback: ((token: String) -> (Void))) {
func getAccessToken(_ callback: @escaping ((_ token: String) -> (Void))) {
if (accessToken == nil || isExpired) {
let url = NSURL(string: "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13")
let url = URL(string: "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13")

let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
var request = URLRequest(url: url!)
request.httpMethod = "POST"

let bodyString = "client_id=\(clientId.urlEncoded!)&client_secret=\(clientSecret.urlEncoded!)&scope=http://api.microsofttranslator.com&grant_type=client_credentials"
request.HTTPBody = bodyString.dataUsingEncoding(NSUTF8StringEncoding)
request.httpBody = bodyString.data(using: String.Encoding.utf8)

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {(data, response, error) in
let task = URLSession.shared.dataTask(with: request, completionHandler: {(data, response, error) in
guard
let data = data,
let resultsDict = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers),
let expiresIn = resultsDict["expires_in"] as? NSString
let resultsDict = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any],
let expiresIn = resultsDict?["expires_in"] as? NSString
else {
callback(token: "")
callback("")
return
}
self.expirationTime = NSDate(timeIntervalSinceNow: expiresIn.doubleValue)
self.expirationTime = Date(timeIntervalSinceNow: expiresIn.doubleValue)

let token = resultsDict["access_token"] as! String
let token = resultsDict?["access_token"] as! String
self.accessToken = token

callback(token: token)
}
callback(token)
})

task.resume()
} else {
callback(token: accessToken!)
callback(accessToken!)
}
}

private var isExpired: Bool {
return expirationTime?.earlierDate(NSDate()) == self.expirationTime
fileprivate var isExpired: Bool {
return (expirationTime as NSDate?)?.earlierDate(Date()) == self.expirationTime
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ import Foundation
extension String {

public var urlEncoded: String? {
let urlQueryAllowedCharacterSet: NSMutableCharacterSet = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy() as! NSMutableCharacterSet
urlQueryAllowedCharacterSet.removeCharactersInString("&=?+")
return self.stringByAddingPercentEncodingWithAllowedCharacters(urlQueryAllowedCharacterSet)
let urlQueryAllowedCharacterSet: NSMutableCharacterSet = (CharacterSet.urlQueryAllowed as NSCharacterSet).mutableCopy() as! NSMutableCharacterSet
urlQueryAllowedCharacterSet.removeCharacters(in: "&=?+")
return self.addingPercentEncoding(withAllowedCharacters: urlQueryAllowedCharacterSet as CharacterSet)
}

public var language: Language? {
if characters.count > 0 { // Prevent Index Out of Bounds in NSLinguisticTagger
let tagger = NSLinguisticTagger(tagSchemes: [NSLinguisticTagSchemeLanguage], options: 0)
let tagger = NSLinguisticTagger(tagSchemes: [NSLinguisticTagScheme.language], options: 0)
tagger.string = self
if let result = tagger.tagAtIndex(0, scheme: NSLinguisticTagSchemeLanguage, tokenRange: nil, sentenceRange: nil) {
return Language(rawValue: result)
if let result = tagger.tag(at: 0, scheme: NSLinguisticTagScheme.language, tokenRange: nil, sentenceRange: nil) {
return Language(rawValue: result.rawValue)
}
}
return nil
Expand Down
Loading