Last active
February 6, 2016 15:51
-
-
Save conradev/8436d3f316d5caed35b4 to your computer and use it in GitHub Desktop.
WFGoogleTranslateSessionManager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// WFGoogleTranslateSessionManager.h | |
// | |
// Created by Conrad Kramer on 2/9/15. | |
// Copyright (c) 2015 DeskConnect. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
NS_ASSUME_NONNULL_BEGIN | |
@interface WFGoogleTranslateSessionManager : NSObject | |
@property (nonatomic, readonly, strong) NSURLSession *session; | |
@property (nonatomic, copy, nullable) NSString *apiKey; | |
@property (nonatomic, copy, nullable) NSString *referer; | |
- (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; | |
- (void)getAvailableLanguages:(void (^)(NSArray * __nullable languages, NSError * __nullable error))completion; | |
- (void)translateStrings:(NSArray<NSString *> *)strings fromLanguage:(nullable NSString *)from intoLanguage:(NSString *)to completion:(void (^)(NSArray<NSString *> * __nullable strings, NSError * __nullable error))completion; | |
- (void)detectLanguagesOfStrings:(NSArray<NSString *> *)strings completion:(void (^)(NSArray<NSString *> * __nullable languages, NSError * __nullable error))completion; | |
@end | |
extern NSString * const WFGoogleTranslateErrorDomain; | |
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// WFGoogleTranslateSessionManager.m | |
// | |
// Created by Conrad Kramer on 2/9/15. | |
// Copyright (c) 2015 DeskConnect. All rights reserved. | |
// | |
#import <UIKit/UIKit.h> | |
#import "WFGoogleTranslateSessionManager.h" | |
NS_ASSUME_NONNULL_BEGIN | |
@interface WFGoogleTranslateSessionManager () | |
@property (nonatomic, readonly, copy) NSURL *baseURL; | |
@end | |
NSString * const WFGoogleTranslateErrorDomain = @"WFGoogleTranslateErrorDomain"; | |
static NSString * const WFGoogleTranslateBaseURLString = @"https://www.googleapis.com/language/translate/v2"; | |
@implementation WFGoogleTranslateSessionManager | |
- (instancetype)init { | |
return [self initWithSessionConfiguration:nil]; | |
} | |
- (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration { | |
self = [super init]; | |
if (!self) | |
return nil; | |
_session = [NSURLSession sessionWithConfiguration:(configuration ?: [NSURLSessionConfiguration defaultSessionConfiguration])]; | |
_baseURL = [NSURL URLWithString:WFGoogleTranslateBaseURLString]; | |
return self; | |
} | |
- (void)getAvailableLanguages:(void (^)(NSArray * __nullable languages, NSError * __nullable error))completion { | |
NSURL *url = [self.baseURL URLByAppendingPathComponent:@"languages"]; | |
[self sendRequestWithURL:url withParameters:nil completion:^(NSDictionary *response, NSError *error) { | |
completion([response valueForKeyPath:@"data.languages.language"], error); | |
}]; | |
} | |
- (void)detectLanguagesOfStrings:(NSArray<NSString *> *)strings completion:(void (^)(NSArray<NSString *> * __nullable languages, NSError * __nullable error))completion { | |
NSMutableArray<NSURLQueryItem *> *parameters = [NSMutableArray new]; | |
for (NSString *string in strings) | |
[parameters addObject:[NSURLQueryItem queryItemWithName:@"q" value:string]]; | |
NSURL *url = [self.baseURL URLByAppendingPathComponent:@"detect"]; | |
[self sendRequestWithURL:url withParameters:parameters completion:^(NSDictionary *response, NSError *error) { | |
NSMutableArray *languages = [NSMutableArray new]; | |
for (NSArray *possibilities in [response valueForKeyPath:@"data.detections.language"]) | |
[languages addObject:possibilities.firstObject]; | |
completion(languages, error); | |
}]; | |
} | |
- (void)translateStrings:(NSArray<NSString *> *)strings fromLanguage:(nullable NSString *)from intoLanguage:(NSString *)to completion:(void (^)(NSArray<NSString *> * __nullable strings, NSError * __nullable error))completion { | |
if (!strings.count) | |
return completion(@[], nil); | |
NSMutableArray<NSURLQueryItem *> *parameters = [NSMutableArray new]; | |
if (from) | |
[parameters addObject:[NSURLQueryItem queryItemWithName:@"source" value:from]]; | |
[parameters addObject:[NSURLQueryItem queryItemWithName:@"target" value:to]]; | |
for (NSString *string in strings) | |
[parameters addObject:[NSURLQueryItem queryItemWithName:@"q" value:string]]; | |
[self sendRequestWithURL:self.baseURL withParameters:parameters completion:^(NSDictionary *response, NSError *error) { | |
NSArray<NSString *> *responseStrings = [response valueForKeyPath:@"data.translations.translatedText"]; | |
if (!responseStrings.count) | |
return completion(nil, error); | |
// Decode HTML entities | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSError *innerError = error; | |
NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}; | |
NSMutableArray *cleanedStrings = [NSMutableArray new]; | |
for (NSString *string in responseStrings) { | |
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding] options:options documentAttributes:nil error:&innerError]; | |
[cleanedStrings addObject:(attributedString.string ?: string)]; | |
} | |
completion([cleanedStrings copy], innerError); | |
}); | |
}]; | |
} | |
- (void)sendRequestWithURL:(NSURL *)url withParameters:(nullable NSArray<NSURLQueryItem *> *)parameters completion:(void (^)(NSDictionary * __nullable response, NSError * __nullable error))completion { | |
NSMutableArray *queryItems = [NSMutableArray arrayWithArray:parameters]; | |
if (self.apiKey) | |
[queryItems insertObject:[NSURLQueryItem queryItemWithName:@"key" value:self.apiKey] atIndex:0]; | |
NSData *body = ({ | |
NSURLComponents *components = [NSURLComponents new]; | |
components.queryItems = queryItems; | |
[components.percentEncodedQuery dataUsingEncoding:NSUTF8StringEncoding]; | |
}); | |
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; | |
[request setHTTPMethod:@"POST"]; | |
[request setValue:@"GET" forHTTPHeaderField:@"X-HTTP-Method-Override"]; | |
[request setValue:self.referer forHTTPHeaderField:@"Referer"]; | |
[request setHTTPBody:body]; | |
[[self.session dataTaskWithRequest:request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) { | |
if (!data.length) | |
return completion(nil, error); | |
NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; | |
NSDictionary *errorObject = responseObject[@"error"]; | |
if (errorObject) { | |
NSMutableDictionary *userInfo = [NSMutableDictionary new]; | |
[userInfo setValue:errorObject[@"message"] forKey:NSLocalizedDescriptionKey]; | |
NSInteger code = [errorObject[@"code"] integerValue]; | |
error = [NSError errorWithDomain:WFGoogleTranslateErrorDomain code:code userInfo:userInfo]; | |
} | |
completion(responseObject, error); | |
}] resume]; | |
} | |
@end | |
NS_ASSUME_NONNULL_END |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment