#import "House.h" @interface House() @property (nonatomic, readwrite) int numberOfBedrooms; @end @implementation House -(instancetype)initWithAddress:(NSString*)address { self = [super init]; if(self){ _address = [address copy]; _numberOfBedrooms = 2; _hasHotTub = false; } return self; } @end
Month: September 2017
House Object Diagram
House
*address
int numberOfBedrooms
bool hasHotTub
-> address
#import <Foundation/Foundation.h> @interface House : NSObject @property (nonatomic) NSString *address @property (nonatomic) int numberOfBetrooms; @property (nonatomic) BOOL hasHotTub; @end
#import <Foundation/Foundation.h> #import "House.h" #import <Foundation/Foundation.h> #import "House.h" int main(int argc, const char * argv[]){ @autoreleasepool { House *myHouse = [[House alloc] init]; } return 0; }
Dynamic Method Resolution
#import <Foundation/Foundation.h> #import "Puppy.h" #import "Dealer.h" #import "Drum.h" int main(int argc, const char * argv[]){ @autoreleasepool { Puppy *spot = [[Puppy alloc] init]; Drum *drum = [[Drum alloc] init]; Dealer *cardDealer = [[Dealer alloc] init]; NSArray *array = @[spot, drum, cardDealer]; NSUInteger index = arc4random_uniform(3); id item = [array objectAtIndex:index]; [item play]; } return 0; }
NSMutableArray *attendance = [NSMutableArray arrayWithArray: @[@”Diego”]];
[attendance addObject:@”Rahul”]
NSArray *invited = @[@”Diego”, @”Rahul”, @”Elana”]
Differences:Handling Nil
Objective-C: Any object can be nil
Swift: Optionals can be nil
#import <Foundation/Foundation.h> #import "Messengaer.h" #import "Package.h" int main(int argc, const char * argv[]){ @autoreleasepool { Messenger +spike = [[Messenger alloc] init]; Package *importantDocuments = [spike pickUpPackage]; NSLog(@"package contents: %@", importantDocuments.contents); } return 0; }
Objective-C and Swift approaches to mutability differ
– how mutability is achieved for a given type
– the probability of an unintended mutation propagating through a program
#import <Foundation/Foundation.h> #import "Messengaer.h" #import "Package.h" int main(int argc, const char * argv[]){ @autoreleasepool { NSArray *kayakingGear = [NSMutableArray arrayWithArray:@[@"halmet",@"paddle",@"boat", @"lifejacket"]]; [kayakingGear addObject:@"booties"]; NSLog(@"%@", kayakingGear); } return 0; }
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 { }
AdMob Console
Register an Account
https://www.google.co.jp/admob/
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(); } }