Localization Tools

project preparation tools
project execution tools
quality assurance tools

translation management, terminology management, translation memory management

In-Context Match Exact(ICE): 100% with context
Exact Match:100%
Fuzzy Match: lower than 99%
No Match: all new words

Localize process

1. Product Preparation
2. Project Preparation
3. Project Execution
4. Quality Assessment

Language tiering
chinese, spanish, english, hindi, arabic, russian

Decide languages -> understand issues and solution -> start designing the app

internationalization:
Process of generalizing a product to handle multiple languages and cultural conventions. It happens during software development.
Design & Engineering, Testing
Density and Fonts, Layout, Spacing, Message Description, Dates, currencies, units, addresses, phone numbers, Plurals and Genders

Psuedolocalization:
Simulation of localized text by replacing source text with fake characters, Improperly Mirrored Interface

Untranslated Text, Not enough space

Project preparation: Project Evaluation: quotation, schedule
overview of project, estimated number of words, deliverables, deadlines, costs

Localization kit
-content to be translated, terminology, translation memories, style guide, reference material
Glossary: Contain the terms that are commonly used in the project and that need to be consistent throughout.
Translation Memory: database that contains all the previously translated segments from a product
Style guide: document outlining a set of standards and best practices in terms of how to handle a specific project

Project execution: Translation
Quality Evaluation Tools

Localization Project

e.g. google Product team
– develop
– introduce new features
– introduce new versions

-> google localization team
-> localization production, language services, vendor management, localization operations
Localization Project Manager(LPM)
-> external localization company: language service provider(LSP)
Language managers(Spanish, Hindi, Traditional Chinese)
Lastly product team launch service globally

Localization operations
– technology, business
Vendor Management finds LSPs, builds relationships

-Requesters, localization project managers, language mangers, localization operations, vendor mangement, external language service providers

User Interface

User Interface:
The space where interactions between humans and machines occur.

e.g. ATM
Withdraw, Deposit, Manage Accounts, Account Blance

Desktop software: applications you download and install onto laptop or desktop computers
Web apps: Similar to desktop applications, but they run on mobile phones and have different considerations
Mobile apps: Similar to traditional software, to use them, you don’t need to install

Where?
UI is found on desktop, web and on the phone.
Who?
UI is used by new users as well as users familiar with the product.
Why?
UI enable users to accomplish goals.
-> lack of product knowledge
Providing message descriptions, Providing Reference material and guidelines

Research what people search in local.
Telefoni Cellulari, Cellulari

English, Turkish, Turkish back translation
hotel chain, otel zinciri, hotel chain
holidays, tail, holiday vacation
hospitality, misavirperverlik, generosity
istanbul hotels, istanbul otelleri, istanbul hotels

localization

In house: engineers, translation team, project manager

Marketing Content: Engaging, Persuasive, Well Written
– First contact with a product
– Used by anyone interested in the product
– Designed to attract potential users

Online help
– FAQS
– Software Documentation
– Troubleshooting Manuals

Product knowledge, Consistent Terminology

Where?
videos are in online help pages, marketing pages, training platforms etc.

Revoicing
voice-over, dubbing, narration, audio description, free commentary

Dubbing:Actors’ voices are recorded over the original audio track
Subtitling:Written translation of spoken words and on-screen text

Nullability Annotations

_Nullable -can have a nil value
-Nonnull -not expected to be nil

@interface Book : NSObject

@property (nonatomic, copy) NSString *title;
@property (nonatomic) Person *author;
@property (nonatomic) Person *editor;
@property (nonatomic) int yearOfPublication;

-(instancetype)initWithTitle:(NSString*)title
	author:(Person*)author
	year:(int)year;

@end

Code for the NSCoding Protocol

class Gif: NSObject, NSCoding {
	let url: NSURL
	let videoURL: NSURL
	let caption: String?
	let gitImage: UIImage
	var gifData: NSData?

	init(url: NSURL, videoURL: NSURL, caption: String?){
		self.url = url
		self.videoURL = videoURL
		self.caption = caption
		self.gifImage = UIImage.gifWithURL(url.absoluteString)!
		self.gifData = nil
	}

	required init?(coder decoder: NSCoder){
		self.url = decoder.decodeObjectForKey("url") as! NSURL
		self.videoURL = decoder.decodeObjectForKey("videoURL") as! NSURL
		self.caption = decoder.decodeObjectForKey("caption") as? String
		self.gifImage = decoder.decodeObjectForKey("gifImage") as! UIImage
		self.gifData = decoder.decodeObjectForKey("gifData") as? NSData
	}

	func encodeWithCoder(coder: NSCoder){
		coder.encodeObject(self.url, forKey: "url")
		coder.encodeObject(self.videoURL, forKey: "videoURL")
		coder.encodeObject(self.caption, forKey: "caption")
		coder.encodeObject(self.gifImage, forKey: "gifImage")
		coder.encodeObject(self.gifData, forKey:"gifData")
	}
}

create the file path

var gifsFilePath: String {
	let directories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
	let documentsPath = directories[0]
	let gifsPath = documentsPath.stringByAppendingString("/savedGifs")
	return gifsPath
}
var gif: Gif?
@IBOutlet weakl var gifImageView: UIImageView!

override func viewDidLoad(){
	super.viewDidLoad()
	gifImageView.image = gif?.gifImage
}

@IBAction func sharedGif(sendr: UIButton){
	var itemsToShare = [NSData]()
	itemsToShare.append((self.gif?gifData)!)

	let activityVC = UIActivityViewController(activityItems: itemsToShare, applicationActivities: nil)
	activityVC.completionWithItemsHandler = {(activity, comleted, items, error) in:
		if (completed){
			self.dismissViewControllerAnimated(true, completion: nil)
		}
	}
	presentViewController(activityVC, animated: true, completion:nil)
}

Enable Video Trimming

imagePicker property settings

func imagePicker(source:UIImagePickerControllerSourceType) -> UIImagePickerController {
	let picker = UIImagePickerController()
	picker.sourceType = source;
	picker.mediaTypes = [kUTTypeMovie as String]
	picker.allowsEditing = true;
	picker.delegate = self;

	return picker
}
func imagePicker(source:UIImagePickerControllerSourceType) -> UIImagePickerController {
	let picker = UIImagePickerController()
	picker.sourceType = source;
	picker.mediaTypes = [kUTTypeMovie as String]
	picker.allowsEditing = true;
	picker.delegate = self;

	return picker	
}

func convertVideToGIF(videoURL: NSURL, start: NSNumber?, duration: NSNumber?){
	dispatch_async(dispatch_get_main_queue()){
		self.dismissViewControllerAnimated(true, completion: nil)
	}

	let regift: Regift;

	if let start = start {
		regift = Regift(sourceFileURL: videoURL, destinationFileURL: nil, startTime: start.floatValue, duration: duration!.floatValue, frameRate: frameRate, loopCount: loopCount)
	} else {
		// Untrimmed
		regift = Regift(sourceFileURL: videoURL, destinationFileURL: nil, frameCount: frameCount, delayTime: delayTime, loopCount: loopCount)
	}

	let gifURL = regif.createGif()
	let gif = Gif(url: gifURL!, rawVideoURL: videoURL, caption: nil)
	displayGIF(gif)
}

public func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo
	info: [String : AnyObject]){
	let mediaType = info[UIImagePickerControllerMediaType] as! String

	if mediaType == kUTTypeMovie as String {

		let videoURL = info[UIImagePickerControllerMediaURL] as! NSURL
		let start: NSNumber? = info["_UIImagePickerControllerVideoEditingStart"] as? NSNumber
		let end: NSNumber? = info["_UIImagePickerControllerVideoEditingEnd"] as? NSNumber	
		var duration: NSNumber?
		if let start = start {
			duration = NSNumber(float: (end!.floatValue) - (start.floatValue))
		} else {
			duration = nil
		}
		convertVideoToGIF(videoURL, start: start, duration: duration)
	}	
}

Make room for keyboard

// Methods to adjust the keyboard
extension GiftEditorViewController {
	func subscribeToKeyboardNotifications(){
		NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(GiftEditorViewController.keyboardWillShow(_:)),
			name: UIKeyboardWillShowNotification,
			object: nil)
		NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(GiftEditorViewController.keyboardWillHide(_:)),
			name: UIKeyboardWillHideNotification,
			object: nil)

	}

	func unsubscribeFromKeyboardNotifications(){
		NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
		NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
	}

	func keyboardWillShow(notification: NSNotification){
		if view.frame.origin.y >= 0 {
			view.frame.origin.y -= getKeyboardHeight(notification)
		}
	}

	func getKeyboardHeight(notification: NSNotification) -> CGFloat{
		let userInfo = notification.userInfo
		let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue
		return keyboardSize.CGRectValue().height
	}
}

Share the GIF

@IBAction func shareGif(sender: AnyObject){
	let url: NSURL = (self.gif?.url)!
	let animatedGIF = NSData(contentsOfURL: url)!
	let itemsToShare = [animatedGIF]

	let activityVC = UIActivityViewController(activityItems: itemToShare, applicationActivities: nil)

	activityVC.completionWithItemsHandler = {(activity, completed, items, error) in
		if(completed){
			self.navigationController?.popToRootViewControllerAnimated(true)
		}
	}

	navigationController?.presentViewController(activityVC, animated: true, completion: nil)
}

Create an Action Sheet

@IBAction func presentVideoOptions(){
	if !UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera){
		//launchPhotoLibrary()
	} else {

		let newGifActionSheet = UIAlertController(title: "Create new GIF", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)

		let recordVideo = UIAlertAction(title: "Record a Video", style: UIAlertActionStyle.Default, handler: {
			(UIAlertAction) in self.launchVideoCamera()
			})
	}
}

Gif class

class Gif {
	let url: NSURL
	let videoURL: NSURL
	let caption: String?
	let gifImage: UIImage?
	var gifData: NSData?

	init(url:NSURL, videoURL: NSURL, caption: String?){

		self.url = url
		self.videoURL = videoURL
		self.caption = caption
		self.gifImage = UIImage.gifWithURL(url.absoluteString)!
		self.gifData = nil
	}

	init(name: String){
		self.gifImage = UIImage.gifWithName(name)
	}
}
#import <UIKit/UIKit.h>
#import "Gif.h"

@interface GifEditorViewController : UIViewController<UITextFeildDelegate>

@property (nonatomic) Gif *gif;
@property (weak, nonatomic) IBOutlet UIImageView *gifImageView;

@end

UITextFieldDelegate Methods

func textFieldDidBeginEditing(textField: UITextField){
	textField.placeholder = ""
}

func textFieldShoudReturn(textField: UITextField) -> Bool {
	textField.resignFirstResponder()
	return true
}