Design pattern

Protocols Enable Shared Functionality Across Classes
pets, dogs, birds, flight, bats, insects

UITextFieldDelegateProtocol in Swift

func textField(textField: UITextField,
	shouldChangeCharactersInRange range:NSRange,
		replacementString string: String) -> Bool {
	
		var newText = textField.text! as NSString
		newText =
		newText.stringByReplacingCharactersInRange(range,
			withString: string)

		return newText.length <= 5
}

UITextFieldDelegateProtocol in Objective-C

-(BOOL)textField:(UITextField *)textField
	shouldChangeCharactersInRange:(NSRange)range
		replacementString:(NSString *)string{

		NSString *nexText = textField.text;
		newText = [newText
		stringByReplacingCharactersInRange:range
			withString:string];

		return (newText.length <=5);
}

Objective-C

Objective-C: Any object can be nil, dynamic typing
Swift: Optionals can be nil, limited mutability
iOS Frameworks Design-Patterns: static typing

// Swift
override func viewWillAppear(animated: Bool){
	super.viewWillAppear(animated)
	displayResult()
}

// Objective-C
- (void)viewWillAppear:(BOOL) animated {
	[super viewWillAppear:animated];
	[self displayResult];
}

AppDelegate Methods

func application(application: UIApplication, didFinishLaunchingWithOptions
	launchOptions: [NSObject: AnyObject]?) -> Bool {
	return true
}
func applicationWillResignActive(application: UIApplication){
}
func applicationDidEnterBackground(application: UIApplication){
}
func applicationWillEnterForeground(application: UIApplication){
}
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
	(NSDictionary *)launchOptions {
	return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application{
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
}

Loading and showing interstitial AD

Interstitial Ad – AdListener
loadAd -> onAdLoaded -> show, isLoaded

public class InterstitialActivity extends Activity {
	private Button mShowButton;
	private InterstitialAd mInterstitial;

	@Override
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_interstitial);

		mShowButton = (Button) findViewById(R.id.showButton);
		mShowButton.setEnabled(false);
	}

	public void loadInterstitial(View unusedView){
		mShowButton.setEnabled(false);
		mShowButton.setText("Loading Interstitial");

		mInterstitial = new InterstitialAd(this);
		mInterstitial.setAdUnitId("ca-app-pub-xxxx/xxxx");
		mInterstitial.astAdListener(new ToastAdListener(this){
			@Override
			public void onAdLoaded(){
				super.onAdLoaded();
				mShowButton.setText("Show Interstitial");
				mShowButton.setEnabled(true);
			}
			@Override
			public void onAdFailedToLoad(int errorCode){
				super.onAdFailedToLoad(errorCode);
				mShowButton.setText(getErrorReason());
			}
			});
			AdRequest.on = new AdRequest.Builder().build();
			mInterstitial.loadAd(ar);
		}

	public void showInterstitial(view unusedView){
		if (mInterstitial.isLoaded()){
			mInterstitial.show();
		}
		mShowButton.setText("Interstitial Not Ready");
		mShowButton.setEnabled(false);
	}
}

loadInterstitial
-Create InterstitialAd
-Set AdUnit Id
-Create Listener – onAdLoaded – show, onAdFailedToLoad – error
-Create AdRequest & LiadAd

Implementing an interstitial AD

InterstitialActivity
callback: loadInterstitial
Disable button
Set text to “Loading Interstitial”
Property: mShowButton
callback: showInterstitial (empty)
set to disable in onCreate

interstitial_ad_unit_id

<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/linearLayout"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<Button
		android:id="@+id/loadButton"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="Load Interstitial"
		android:onClick="loadInterstitial"/>
	<Button
		android:id="@+id/showButton"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="Interstitial Not Ready"
		android:onClick="showInterstitial" />
</LinearLayout>	
public class InterstitialActivity extends Activity {
	private Button mShowButton;

	@Override
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_interstitial);

		mShowButton = (Button) findViewById(R.id.showButton);
		mShowButton.setEnabled(false);
	}

	public void loadInterstitial(View unusedView){
		mShowButton.setEnabled(false);
		mShowButton.setText("Loading Interstitial");
	}

	public void showInterstitial(view unusedView){
	}
}

Adding AdListener

import ...

public class ToastAdListener extends AdListener {
	private Context mContext;
	private String mErrorReason;

	public ToastAdListener(Context context) { this.mContext = context; }

	@Override
	public void onAdLoaded(){
		Toast.makeText(mContext,
			"onAdLoaded()",
			Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onAdOpened(){
		Toast.makeText(mContext,
			"onAdOpened()",
			Toast.LENGTH_SHORT).show();
	}
}

Banner Ad

package com.example.adviewer;

import ...

public class BannerActivity extends Activity {
	private AdView mAdView;

	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_banner);

		mAdView = (AdView) findViewById(R.id.adView);
		AdRequest adRequest = new AdRequest.Builder()
			.build();
		mAdView.loadAd(adRequest);
	}
}

AdListener
public void onAdLoaded()
public void onAdFailedToLoad(int code) {AdRequest Error}
public void onAdOpened()
public void onAdLeftApplication() (e.g. BROWSER)

AdMob

Easy to Launch, Long Term, User Value
Paid Donwloads: no, no, yes
Subscription: no, yes, yes
Displaying ADs: yes, yes, yes
In-app purchase: yes, yes, yes

Common Monetization Models
-ADs & In-app purchases, subscription & in-app purchases, paid download & in-app purchases

USERS -> APPS(publishers) -> AdMob -> ADVERTISERS
https://www.google.co.jp/admob/

Types of ADs
-Banner ADs: TEXT, Image
-Interstitional ADs: Text, image, video
-Native ADs

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:ads="http://schemas.android.com/apk/res-auto"
	android:id="@+id/mainLayout"
	android:layout_width="match_parent"
	android:layout_height="match_parent">

	<com.google.android.gms.ads.AdView
		android:id="@+id/adView"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:layout_alignParentBottom="true"
		android:layout_alignParentLeft="true"
		ads:adSize="BANNER"
		ads:adUnitId="cp-app-pub-xxxx/xxxx"/>
</RelativeLayout>

Mapper and Reducer

import sys
import string
import logging

from util import mapper_logfile
logging.basicConfig(filename=mapper_logfile, format='%(message)s',
	level=logging.INFO, filemode='w')

def mapper():
	for line in sys.stdin:

		data = line.strip().split(",")
		if len(data) != 12 or data[0] == 'Register':
			continue
		print "{0}\t{1}".format(data[3], data[8])

mapper()
import sys
import logging

from util import reducer_logfile
logging.basicConfig(filename=reducer_logfile, format='%(message)s',
	level=logging.INFO, filemode='w')

def reducer():

	aadhaar_generated = 0
	old_key = None

	for line in sys.stdin:
		data = line.strip().split("\t")

		if len(data) != 2:
			continue

		this_key, count = data
		if old_key and old_key != this_key:
			print "{0}\t{1}".format(old_key, aadhaar_generated)

			aadhaar_generated = 0

		old_key = this_key
		aadhaar_generated += float(count)

	if old_key != None:
		print "{0}\t{1}".format(old_key, aadhaar_generated)

reducer()

Mapreduce programming model -> HADOOP!
(1)Hive, (2)Pig
mahout, giraph, cassandra

Using Mapreduce with Subway data

Mapper

def mapper():

	for line in sys.stdin:

		data = line.strip.split("")

		for i in data:
			cleaned_data = i.translate(string.maketrans("",""), string.punctuation).lower()
			print "{0}\t{t}".format(cleaned_data,1)

			mapper()

Reduce stage -> reducer

import sys

def reducer():
	word_count = 0
	old_key = None

	for line in sys.stdin:
		data = line.strip().split("\t")

		if len(data) != 2:
			continue

		if old_key and old_key != this_key: 
			print"{0}\t{1}".format(old_key, word_count)
			word_count = 0

		old_key = this_key
		word_count += float(count)

	if old_key != None:
		print "{0}\t{1}".format(old_key, word_count)
#! /bin/bash

cat ../../data/aliceInWorderland.txt | python word_count_mapper.py | sort | python word_count_reducer.py