iOS下内存管理的基本思想就是引用计数,通过对象的引用计数来对内存对象的生命周期进行控制。具体到编程时间方面,主要有两种方式:
1:MRR(manual retain-release),人工引用计数,对象的生成、销毁、引用计数的变化都是由开发人员来完成。
2:ARC(Automatic Reference Counting),自动引用计数,只负责对象的生成,其他过程开发人员不再需要关心其销毁,使用方式类似于垃圾回收,但其实质还是引用计数。
根据苹果说明文档,面临的两个主要问题是:
释放或覆盖的数据仍然在使用。这将造成内存损坏,通常在应用程序崩溃,或者更糟,损坏用户数据。
不释放不再使用的数据会导致内存泄漏。分配的内存,内存泄漏不会释放,即使它从来没有再次使用。泄漏会导致应用程序的内存使用量日益增加,这反过来又可能会导致系统性能较差或死机。
我们创建自己的对象,当他们不再需要的时候,释放他们。
保留需要使用的对象。如果没有必要必须释放这些对象。
不要释放我们没有拥有的对象。
可以用Xcode工具仪器的帮助下分析内存的使用情况。它包括的工具有活动监视器,分配,泄漏,僵尸等
1. 打开一个现有的应用程序。
2. 选择产品,配置文件如下所示
3.在以下界面中选择 Allocations 和 Profile。
4. 我们可以看到不同对象的内存使用情况
5. 你可以切换视图控制器查看内存是否释放。
6.同样我们可以使用 Activity Monitor 来查看内存在应用程序中的分配的情况。
7. 这些工具可以帮助我们了解内存的使用情况及在什么地方可能发生泄漏。
Twitter已经整合到iOS5.0,而Facebook已经被集成在 iOS 6.0中。本教程的重点讲解如何利用苹果提供的类在iOS5.0和iOS6.0中部署Twitter和Facebook。
1. 创建一个简单View based application
2. 选择项目文件,然后选择"targets(目标)",然后在 choose frameworks(选择框架)中添加Social.framework 和 Accounts.framework
3. 添加两个名为facebookPost 和 twitterPost的按钮,并为他们创建 ibActions。
4. 更新 ViewController.h 如下
#import <Social/Social.h>#import <Accounts/Accounts.h>#import <UIKit/UIKit.h>@interface ViewController : UIViewController-(IBAction)twitterPost:(id)sender;-(IBAction)facebookPost:(id)sender;@end
5. 更新ViewController.m ,如下所示
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad];}- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(IBAction)facebookPost:(id)sender{ SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook]; SLComposeViewControllerCompletionHandler myBlock = ^(SLComposeViewControllerResult result){ if (result == SLComposeViewControllerResultCancelled) { NSLog(@"Cancelled"); } else { NSLog(@"Done"); } [controller dismissViewControllerAnimated:YES completion:nil]; }; controller.completionHandler =myBlock; //Adding the Text to the facebook post value from iOS [controller setInitialText:@"My test post"]; //Adding the URL to the facebook post value from iOS [controller addURL:[NSURL URLWithString:@"http://www.test.com"]]; //Adding the Text to the facebook post value from iOS [self presentViewController:controller animated:YES completion:nil]; }-(IBAction)twitterPost:(id)sender{ SLComposeViewController *tweetSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter]; [tweetSheet setInitialText:@"My test tweet"]; [self presentModalViewController:tweetSheet animated:YES];}@end
运行该应用程序并单击 facebookPost 时我们将获得以下输出
当我们单击 twitterPost 时,我们将获得以下输出
自动布局在iOS 6.0中引入,仅可以支持IOS6.0 及 更高版本。它可以帮助我们创建用于多个种设备的界面。
1.创建一个简单的 View based application
2.修改 ViewController.m 的文件内容,如下所示
#import "ViewController.h"@interface ViewController ()@property (nonatomic, strong) UIButton *leftButton;@property (nonatomic, strong) UIButton *rightButton;@property (nonatomic, strong) UITextField *textfield;@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; UIView *superview = self.view; /*1. Create leftButton and add to our view*/ self.leftButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; self.leftButton.translatesAutoresizingMaskIntoConstraints = NO; [self.leftButton setTitle:@"LeftButton" forState:UIControlStateNormal]; [self.view addSubview:self.leftButton]; /* 2. Constraint to position LeftButton's X*/ NSLayoutConstraint *leftButtonXConstraint = [NSLayoutConstraint constraintWithItem:self.leftButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:superview attribute: NSLayoutAttributeCenterX multiplier:1.0 constant:-60.0f]; /* 3. Constraint to position LeftButton's Y*/ NSLayoutConstraint *leftButtonYConstraint = [NSLayoutConstraint constraintWithItem:self.leftButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:superview attribute: NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]; /* 4. Add the constraints to button's superview*/ [superview addConstraints:@[ leftButtonXConstraint, leftButtonYConstraint]]; /*5. Create rightButton and add to our view*/ self.rightButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; self.rightButton.translatesAutoresizingMaskIntoConstraints = NO; [self.rightButton setTitle:@"RightButton" forState:UIControlStateNormal]; [self.view addSubview:self.rightButton]; /*6. Constraint to position RightButton's X*/ NSLayoutConstraint *rightButtonXConstraint = [NSLayoutConstraint constraintWithItem:self.rightButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:superview attribute: NSLayoutAttributeCenterX multiplier:1.0 constant:60.0f]; /*7. Constraint to position RightButton's Y*/ rightButtonXConstraint.priority = UILayoutPriorityDefaultHigh; NSLayoutConstraint *centerYMyConstraint = [NSLayoutConstraint constraintWithItem:self.rightButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:superview attribute: NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]; [superview addConstraints:@[centerYMyConstraint, rightButtonXConstraint]]; //8. Add Text field self.textfield = [[UITextField alloc]initWithFrame: CGRectMake(0, 100, 100, 30)]; self.textfield.borderStyle = UITextBorderStyleRoundedRect; self.textfield.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:self.textfield]; //9. Text field Constraints NSLayoutConstraint *textFieldTopConstraint = [NSLayoutConstraint constraintWithItem:self.textfield attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:60.0f]; NSLayoutConstraint *textFieldBottomConstraint = [NSLayoutConstraint constraintWithItem:self.textfield attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.rightButton attribute:NSLayoutAttributeTop multiplier:0.8 constant:-60.0f]; NSLayoutConstraint *textFieldLeftConstraint = [NSLayoutConstraint constraintWithItem:self.textfield attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:superview attribute: NSLayoutAttributeLeft multiplier:1.0 constant:30.0f]; NSLayoutConstraint *textFieldRightConstraint = [NSLayoutConstraint constraintWithItem:self.textfield attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:superview attribute: NSLayoutAttributeRight multiplier:1.0 constant:-30.0f]; [superview addConstraints:@[textFieldBottomConstraint , textFieldLeftConstraint, textFieldRightConstraint, textFieldTopConstraint]]; }- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
运行应用程序,在 iPhone 模拟器上会有下面的输出结果
当我们更改模拟器为横向的方向时,输出结果如下
我们在 iPhone 5 模拟器上运行同一应用程序时,输出结果如下
当我们更改模拟器为横向的方向时,输出结果如下:
当我们做应用程序的时候,可能会犯各种错误,这可能会导致各种不同的错误。因此,为了修复这些错误或缺陷,我们需要来调试应用程序。
Xcode中调试器即 GDB 和 LLDB 调试器,GDB 是默认的。 LLDB是一个调试器是LLVM开源的编译器项目的一部分。您可以更改调试,编辑活动计划选项。
我们只需要建立我们的应用程序,代码被编译器编译,所有的消息,错误和警告将显示以及错误的原因,我们可以纠正他们。可以点击 product,然后点击"分析",将在应用程序中可能发生的问题。
断点帮助我们了解我们的应用程序对象,帮助我们找出许多缺陷,包括逻辑问题的不同状态。我们只需要点击创建一个断点的行号。我们可以通过点击并拖动它删除断点。如下所示
当我们运行应用程序并选择playVideo,按钮的应用程序将被暂停,我们来分析一下我们的应用程序的状态。当断点被触发时,我们将得到一个输出,如下图所示
可以轻松地确定哪个线程触发断点。在底部可以看到对象,如self,sender等,这些持有相应的对象的值,我们可以展开一些这些对象,看看他们每个的状态是什么。
要继续应用程序,我们在调试区选择继续按钮(最左边的按钮),如下图所示。其他选项包括步骤和单步跳过
我们也有异常断点,触发应用程序停止发生异常的位置。通过选择调试导航后选择"+"按钮,我们可以创建异常断点。将得到下面的窗口
然后,我们需要选择" Exception Breakpoint (添加异常)"断点,它会显示下面的窗口
你可以在 Xcode 4 用户指南 知道更多关于调试和其他Xcode功能的知识。
Storyboards在 iOS 5 中才有介绍,当我们用Storyboards时,部署目标应该是iOS5.0或更高版本。
Storyboards 帮助我们了解视觉流动的画面,在界面为
MainStoryboard.storyboard下创建所有应用程序屏幕。
1. 创建一个single view application,创建应用程序时选择 storyboard 复选框。
2. 选择MainStoryboard.storyboard,在这里你可以找到单一视图控制器。添加一个视图控制器,更新视图控制器,如下所示
3.连接两个视图控制器。右键单击"show modal(显示模式)"按钮,在左侧视图控制器将其拖动到右视视图控制器中,如下图所示:
4.现在从如下所示的三个显示选项中选择modal(模态)
5.更新 ViewController.h 如下所示
#import <UIKit/UIKit.h>@interface ViewController : UIViewController-(IBAction)done:(UIStoryboardSegue *)seque;@end
6.更新 ViewController.m 如下所示
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; }- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(IBAction)done:(UIStoryboardSegue *)seque{ [self.navigationController popViewControllerAnimated:YES];}@end
7.选择"MainStoryboard.storyboard",并右键点击"Exit "按钮,在右侧视图控制器中选择和连接后退按钮,如下图所示
在iPhone设备中运行该应用程序,得到如下输出结果
现在,选择显示模式,将得到下面的输出结果
音频和视频在最新的设备中颇为常见。
将iosAVFoundation.framework和MediaPlayer.framework添加到Xcode项目中,可以让IOS支持音频和视频(Audio & Video)。
1、创建一个简单的View based application
2、选择项目文件、选择目标,然后添加AVFoundation.framework和MediaPlayer.framework
3、在ViewController.xib中添加两个按钮,创建一个用于分别播放音频和视频的动作(action)
4、更新ViewController.h,如下所示
#import <UIKit/UIKit.h>#import <AVFoundation/AVFoundation.h>#import <MediaPlayer/MediaPlayer.h>@interface ViewController : UIViewController{ AVAudioPlayer *audioPlayer; MPMoviePlayerViewController *moviePlayer; }-(IBAction)playAudio:(id)sender;-(IBAction)playVideo:(id)sender;@end
5、更新ViewController.m,如下所示
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad];}- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(IBAction)playAudio:(id)sender{ NSString *path = [[NSBundle mainBundle] pathForResource:@"audioTest" ofType:@"mp3"]; audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL: [NSURL fileURLWithPath:path] error:NULL]; [audioPlayer play];}-(IBAction)playVideo:(id)sender{ NSString *path = [[NSBundle mainBundle]pathForResource: @"videoTest" ofType:@"mov"]; moviePlayer = [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL fileURLWithPath:path]]; [self presentModalViewController:moviePlayer animated:NO];}@end
需要添加音频和视频文件,以确保获得预期的输出
运行该程序,得到的输出结果如下
当我们点击 play video(播放视频)显示如下:
我们可以使用IOS设备中的电子邮件应用程序发送电子邮件。
1、创建一个简单的View based application
2、选择项目文件,然后选择目标,然后添加MessageUI.framework
3、在ViewController.xib中添加一个按钮,创建用于发送电子邮件的操作(action)
4、更新ViewController.h,如下所示
#import <UIKit/UIKit.h>#import <MessageUI/MessageUI.h>@interface ViewController : UIViewController<MFMailComposeViewControllerDelegate>{ MFMailComposeViewController *mailComposer;}-(IBAction)sendMail:(id)sender;@end
5、如下所示,更新ViewController.m
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; }- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(void)sendMail:(id)sender{ mailComposer = [[MFMailComposeViewController alloc]init]; mailComposer.mailComposeDelegate = self; [mailComposer setSubject:@"Test mail"]; [mailComposer setMessageBody:@"Testing message for the test mail" isHTML:NO]; [self presentModalViewController:mailComposer animated:YES];}#pragma mark - mail compose delegate-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{ if (result) { NSLog(@"Result : %d",result); } if (error) { NSLog(@"Error : %@",error); } [self dismissModalViewControllerAnimated:YES];}@end
当运行该应用程序,会看如下的输出结果
当点击"send email"发送按钮后,可以看到如下结果:
在IOS中使用Sqlite来处理数据。如果你已经了解了SQL,那你可以很容易的掌握SQLite数据库的操作。
1、创建一个简单的View based application
2、选择项目文件,然后选择目标,添加libsqlite3.dylib库到选择框架
3、通过选择" File-> New -> File... -> "选择 Objective C class 创建新文件,单击下一步
4、"sub class of"为NSObject",类命名为DBManager
5、选择创建
6、更新DBManager.h,如下所示
#import <Foundation/Foundation.h>#import <sqlite3.h>@interface DBManager : NSObject{ NSString *databasePath;}+(DBManager*)getSharedInstance;-(BOOL)createDB;-(BOOL) saveData:(NSString*)registerNumber name:(NSString*)name department:(NSString*)department year:(NSString*)year;-(NSArray*) findByRegisterNumber:(NSString*)registerNumber;@end
7、更新DBManager.m,如下所示
#import "DBManager.h"static DBManager *sharedInstance = nil;static sqlite3 *database = nil;static sqlite3_stmt *statement = nil;@implementation DBManager+(DBManager*)getSharedInstance{ if (!sharedInstance) { sharedInstance = [[super allocWithZone:NULL]init]; [sharedInstance createDB]; } return sharedInstance;}-(BOOL)createDB{ NSString *docsDir; NSArray *dirPaths; // Get the documents directory dirPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); docsDir = dirPaths[0]; // Build the path to the database file databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"student.db"]]; BOOL isSuccess = YES; NSFileManager *filemgr = [NSFileManager defaultManager]; if ([filemgr fileExistsAtPath: databasePath ] == NO) { const char *dbpath = [databasePath UTF8String]; if (sqlite3_open(dbpath, &database) == SQLITE_OK) { char *errMsg; const char *sql_stmt = "create table if not exists studentsDetail (regno integer primary key, name text, department text, year text)"; if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) { isSuccess = NO; NSLog(@"Failed to create table"); } sqlite3_close(database); return isSuccess; } else { isSuccess = NO; NSLog(@"Failed to open/create database"); } } return isSuccess;}- (BOOL) saveData:(NSString*)registerNumber name:(NSString*)name department:(NSString*)department year:(NSString*)year;{ const char *dbpath = [databasePath UTF8String]; if (sqlite3_open(dbpath, &database) == SQLITE_OK) { NSString *insertSQL = [NSString stringWithFormat:@"insert into studentsDetail (regno,name, department, year) values ("%d","%@", "%@", "%@")",[registerNumber integerValue], name, department, year]; const char *insert_stmt = [insertSQL UTF8String]; sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL); if (sqlite3_step(statement) == SQLITE_DONE) { return YES; } else { return NO; } sqlite3_reset(statement); } return NO;}- (NSArray*) findByRegisterNumber:(NSString*)registerNumber{ const char *dbpath = [databasePath UTF8String]; if (sqlite3_open(dbpath, &database) == SQLITE_OK) { NSString *querySQL = [NSString stringWithFormat: @"select name, department, year from studentsDetail where regno="%@"",registerNumber]; const char *query_stmt = [querySQL UTF8String]; NSMutableArray *resultArray = [[NSMutableArray alloc]init]; if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK) { if (sqlite3_step(statement) == SQLITE_ROW) { NSString *name = [[NSString alloc] initWithUTF8String: (const char *) sqlite3_column_text(statement, 0)]; [resultArray addObject:name]; NSString *department = [[NSString alloc] initWithUTF8String: (const char *) sqlite3_column_text(statement, 1)]; [resultArray addObject:department]; NSString *year = [[NSString alloc]initWithUTF8String: (const char *) sqlite3_column_text(statement, 2)]; [resultArray addObject:year]; return resultArray; } else{ NSLog(@"Not found"); return nil; } sqlite3_reset(statement); } } return nil;}
8、如图所示,更新ViewController.xib文件
9、为上述文本字段创建IBOutlets
10、为上述按钮创建IBAction
11、如下所示,更新ViewController.h
#import <UIKit/UIKit.h>#import "DBManager.h"@interface ViewController : UIViewController<UITextFieldDelegate>{ IBOutlet UITextField *regNoTextField; IBOutlet UITextField *nameTextField; IBOutlet UITextField *departmentTextField; IBOutlet UITextField *yearTextField; IBOutlet UITextField *findByRegisterNumberTextField; IBOutlet UIScrollView *myScrollView;}-(IBAction)saveData:(id)sender;-(IBAction)findData:(id)sender;@end
12、更新ViewController.m,如下所示
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *) nibBundleOrNil{ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self;}- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view from its nib.}- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(IBAction)saveData:(id)sender{ BOOL success = NO; NSString *alertString = @"Data Insertion failed"; if (regNoTextField.text.length>0 &&nameTextField.text.length>0 && departmentTextField.text.length>0 &&yearTextField.text.length>0 ) { success = [[DBManager getSharedInstance]saveData: regNoTextField.text name:nameTextField.text department: departmentTextField.text year:yearTextField.text]; } else{ alertString = @"Enter all fields"; } if (success == NO) { UIAlertView *alert = [[UIAlertView alloc]initWithTitle: alertString message:nil delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; }}-(IBAction)findData:(id)sender{ NSArray *data = [[DBManager getSharedInstance]findByRegisterNumber: findByRegisterNumberTextField.text]; if (data == nil) { UIAlertView *alert = [[UIAlertView alloc]initWithTitle: @"Data not found" message:nil delegate:nil cancelButtonTitle: @"OK" otherButtonTitles:nil]; [alert show]; regNoTextField.text = @""; nameTextField.text =@""; departmentTextField.text = @""; yearTextField.text =@""; } else{ regNoTextField.text = findByRegisterNumberTextField.text; nameTextField.text =[data objectAtIndex:0]; departmentTextField.text = [data objectAtIndex:1]; yearTextField.text =[data objectAtIndex:2]; }}#pragma mark - Text field delegate-(void)textFieldDidBeginEditing:(UITextField *)textField{ [myScrollView setFrame:CGRectMake(10, 50, 300, 200)]; [myScrollView setContentSize:CGSizeMake(300, 350)];}-(void)textFieldDidEndEditing:(UITextField *)textField{ [myScrollView setFrame:CGRectMake(10, 50, 300, 350)];}-(BOOL) textFieldShouldReturn:(UITextField *)textField{ [textField resignFirstResponder]; return YES;}@end
现在当我们运行应用程序时,我们就会获得下面的输出,我们可以在其中添加及查找学生的详细信息
GameKit是iOS SDK中一个常用的框架。其核心功能有3个:
1.在链接 iTunes 时请确保拥有一个唯一的 App ID( unique App ID),App ID在我们应用程序更新 bundle ID时及在Xcode代码签名与相应的配置文件需要使用到。
2.创建新的应用程序和更新应用程序信息。在添加新的应用程序文档可以了解更多有关信息。
3.打开你申请的application,点击Manage Game Center选项。进入后点击Enable Game Center使你的Game Center生效。接下来设置自己的Leaderboard和Achievements。
4.下一步涉及处理代码,并为我们的应用程序创建用户界面。
5.创建一个single view application,并输入 bundle identifier 。
6.更新 ViewController.xib,如下所示
7.选择项目文件,然后选择目标,然后添加GameKit.framework
8.为已添加的按钮创建IBActions
9.更新ViewController.h文件,如下所示
#import <UIKit/UIKit.h>#import <GameKit/GameKit.h>@interface ViewController : UIViewController<GKLeaderboardViewControllerDelegate>-(IBAction)updateScore:(id)sender;-(IBAction)showLeaderBoard:(id)sender;@end
10.更新ViewController.m ,如下所示
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; if([GKLocalPlayer localPlayer].authenticated == NO) { [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) { NSLog(@"Error%@",error); }]; } }- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}- (void) updateScore: (int64_t) score forLeaderboardID: (NSString*) category{ GKScore *scoreObj = [[GKScore alloc] initWithCategory:category]; scoreObj.value = score; scoreObj.context = 0; [scoreObj reportScoreWithCompletionHandler:^(NSError *error) { // Completion code can be added here UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Score Updated Succesfully" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; }];}-(IBAction)updateScore:(id)sender{ [self updateScore:200 forLeaderboardID:@"tutorialsPoint"];}-(IBAction)showLeaderBoard:(id)sender{ GKLeaderboardViewController *leaderboardViewController = [[GKLeaderboardViewController alloc] init]; leaderboardViewController.leaderboardDelegate = self; [self presentModalViewController: leaderboardViewController animated:YES];}#pragma mark - Gamekit delegates- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController{ [self dismissModalViewControllerAnimated:YES];}@end
运行该应用程序,输出结果如下
当我们单击显示排行榜时,屏幕显示如下:
当我们点击更新分数,比分将被更新到我们排行榜上,我们会得到一个信息,如下图所示
在IOS中通过CoreLocation定位,可以获取到用户当前位置,同时能得到装置移动信息。
1、创建一个简单的View based application(视图应用程序)。
2、择项目文件,然后选择目标,然后添加CoreLocation.framework,如下所示
3、在ViewController.xib中添加两个标签,创建ibOutlet名为latitudeLabel和longtitudeLabel的标签
4、现在通过选择" File-> New -> File... -> "选择Objective C class 并单击下一步
5、把"sub class of"作为NSObject,将类命名为LocationHandler
6、选择创建
7、更新LocationHandler.h,如下所示
#import <Foundation/Foundation.h>#import <CoreLocation/CoreLocation.h>@protocol LocationHandlerDelegate <NSObject>@required-(void) didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation;@end@interface LocationHandler : NSObject<CLLocationManagerDelegate>{ CLLocationManager *locationManager;}@property(nonatomic,strong) id<LocationHandlerDelegate> delegate;+(id)getSharedInstance;-(void)startUpdating;-(void) stopUpdating;@end
8、更新LocationHandler.m,如下所示
#import "LocationHandler.h"static LocationHandler *DefaultManager = nil;@interface LocationHandler()-(void)initiate;@end@implementation LocationHandler+(id)getSharedInstance{ if (!DefaultManager) { DefaultManager = [[self allocWithZone:NULL]init]; [DefaultManager initiate]; } return DefaultManager;}-(void)initiate{ locationManager = [[CLLocationManager alloc]init]; locationManager.delegate = self;}-(void)startUpdating{ [locationManager startUpdatingLocation];}-(void) stopUpdating{ [locationManager stopUpdatingLocation];}-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ if ([self.delegate respondsToSelector:@selector (didUpdateToLocation:fromLocation:)]) { [self.delegate didUpdateToLocation:oldLocation fromLocation:newLocation]; }}@end
9、更新ViewController.h,如下所示
#import <UIKit/UIKit.h>#import "LocationHandler.h"@interface ViewController : UIViewController<LocationHandlerDelegate>{ IBOutlet UILabel *latitudeLabel; IBOutlet UILabel *longitudeLabel;}@end
10、更新ViewController.m,如下所示
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; [[LocationHandler getSharedInstance]setDelegate:self]; [[LocationHandler getSharedInstance]startUpdating];}- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(void)didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ [latitudeLabel setText:[NSString stringWithFormat: @"Latitude: %f",newLocation.coordinate.latitude]]; [longitudeLabel setText:[NSString stringWithFormat: @"Longitude: %f",newLocation.coordinate.longitude]];}@end
当我们运行该应用程序,会得到如下的输出:
IAD是苹果推出的广告平台,它可以帮助开发者从应用程序中获取收入。
1. 创建一个简单的View based application
2. 选择项目文件,然后选择目标,然后选择框架并添加 iAd.framework。
3. 更新 ViewController.h 如下所示
#import <UIKit/UIKit.h>#import <iAd/iAd.h>@interface ViewController : UIViewController<ADBannerViewDelegate>{ ADBannerView *bannerView;}@end
4. 更新ViewController.m ,如下所示
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; bannerView = [[ADBannerView alloc]initWithFrame: CGRectMake(0, 0, 320, 50)]; // Optional to set background color to clear color [bannerView setBackgroundColor:[UIColor clearColor]]; [self.view addSubview: bannerView];}- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}#pragma mark - AdViewDelegates-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{ NSLog(@"Error loading");}-(void)bannerViewDidLoadAd:(ADBannerView *)banner{ NSLog(@"Ad loaded");}-(void)bannerViewWillLoadAd:(ADBannerView *)banner{ NSLog(@"Ad will load");}-(void)bannerViewActionDidFinish:(ADBannerView *)banner{ NSLog(@"Ad did finish");}@end
运行该应用程序,得到如下输出结果:
应用程序内购买是应用程序用于购买额外内容或升级功能。
1.在 iTunes 连接中请确保拥有一个唯一的 App ID(unique App ID ),当创建捆绑的ID( bundle ID)应用程序更新时,代码会以相应的配置文件签名在Xcode上
2.创建新的应用程序和更新应用程序信息。你可以知道更多有关的,在苹果的 添加新的应用程序 文档中
3.在应用程序页的管理应用程序( Manage In-App Purchase)中,为app内付费添加新产品
4.确保设置的应用程序为的银行详细。需要将其设置为在应用程序内购买(In-App purchase)。此外在 iTunes 中使用管理用户(Manage Users)选项,创建一个测试用户帐户连接您的应用程序的页。
5.下一步是与处理代码和为我们在应用程序内购买创建有关的 UI。
6.创建一个单一的视图应用程序,并在 iTunes 中指定的标识符连接输入捆绑标识符
7.更新ViewController.xib ,如下所示
8.为三个标签创建IBOutlets,且将按钮分别命名为 productTitleLabel、 productDescriptionLabel、 productPriceLabel 和 purchaseButton
9.选择项目文件,然后选择目标,然后添加StoreKit.framework
10.更新ViewController.h ,如下所示
#import <UIKit/UIKit.h>#import <StoreKit/StoreKit.h>@interface ViewController : UIViewController< SKProductsRequestDelegate,SKPaymentTransactionObserver>{ SKProductsRequest *productsRequest; NSArray *validProducts; UIActivityIndicatorView *activityIndicatorView; IBOutlet UILabel *productTitleLabel; IBOutlet UILabel *productDescriptionLabel; IBOutlet UILabel *productPriceLabel; IBOutlet UIButton *purchaseButton;}- (void)fetchAvailableProducts;- (BOOL)canMakePurchases;- (void)purchaseMyProduct:(SKProduct*)product;- (IBAction)purchase:(id)sender;@end
11.更新ViewController.m ,如下所示
#import "ViewController.h"#define kTutorialPointProductID @"com.tutorialPoints.testApp.testProduct"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; // Adding activity indicator activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; activityIndicatorView.center = self.view.center; [activityIndicatorView hidesWhenStopped]; [self.view addSubview:activityIndicatorView]; [activityIndicatorView startAnimating]; //Hide purchase button initially purchaseButton.hidden = YES; [self fetchAvailableProducts]; }- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(void)fetchAvailableProducts{ NSSet *productIdentifiers = [NSSet setWithObjects:kTutorialPointProductID,nil]; productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers]; productsRequest.delegate = self; [productsRequest start];}- (BOOL)canMakePurchases{ return [SKPaymentQueue canMakePayments];}- (void)purchaseMyProduct:(SKProduct*)product{ if ([self canMakePurchases]) { SKPayment *payment = [SKPayment paymentWithProduct:product]; [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } else{ UIAlertView *alertView = [[UIAlertView alloc]initWithTitle: @"Purchases are disabled in your device" message:nil delegate: self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alertView show]; }}-(IBAction)purchase:(id)sender{ [self purchaseMyProduct:[validProducts objectAtIndex:0]]; purchaseButton.enabled = NO; }#pragma mark StoreKit Delegate-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchasing: NSLog(@"Purchasing"); break; case SKPaymentTransactionStatePurchased: if ([transaction.payment.productIdentifier isEqualToString:kTutorialPointProductID]) { NSLog(@"Purchased "); UIAlertView *alertView = [[UIAlertView alloc]initWithTitle: @"Purchase is completed succesfully" message:nil delegate: self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alertView show]; } [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; break; case SKPaymentTransactionStateRestored: NSLog(@"Restored "); [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; break; case SKPaymentTransactionStateFailed: NSLog(@"Purchase failed "); break; default: break; } }}-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ SKProduct *validProduct = nil; int count = [response.products count]; if (count>0) { validProducts = response.products; validProduct = [response.products objectAtIndex:0]; if ([validProduct.productIdentifier isEqualToString:kTutorialPointProductID]) { [productTitleLabel setText:[NSString stringWithFormat: @"Product Title: %@",validProduct.localizedTitle]]; [productDescriptionLabel setText:[NSString stringWithFormat: @"Product Desc: %@",validProduct.localizedDescription]]; [productPriceLabel setText:[NSString stringWithFormat: @"Product Price: %@",validProduct.price]]; } } else { UIAlertView *tmp = [[UIAlertView alloc] initWithTitle:@"Not Available" message:@"No products to purchase" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil]; [tmp show]; } [activityIndicatorView stopAnimating]; purchaseButton.hidden = NO;}@end
注意: 需要修改你创建In-App Pur(应用内购买)的 kTutorialPointProductID 。通过修改fetchAvailableProducts产品标识符的 NSSet, 你可以添加多个产品。
运行该应用程序,输出结果如下
确保已经中登录。单击购买选择现有的Apple ID。输入有效的测试帐户的用户名和密码。几秒钟后,显示下面的信息
一旦产品成功购买,将获得以下信息。可以在显示此信息的地方,更新应用功能相关的代码
IOS地图帮助我们定位位置,IOS地图使用 MapKit 框架。
1.创建一个简单的 View based application
2.选择项目文件,然后选择目标,然后添加MapKit.framework.
3.添加 Corelocation.framework
4.向 ViewController.xib 添加地图查看和创建 ibOutlet 并且命名为mapView。
5.通过"File-> New -> File... -> "选择 Objective C class创建一个新的文件,单击下一步
6."sub class of"为 NSObject,类作命名为MapAnnotation
7.选择创建
8.更新MapAnnotation.h ,如下所示
#import <Foundation/Foundation.h>#import <MapKit/MapKit.h>@interface MapAnnotation : NSObject<MKAnnotation>@property (nonatomic, strong) NSString *title;@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;- (id)initWithTitle:(NSString *)title andCoordinate: (CLLocationCoordinate2D)coordinate2d;@end
9.更新MapAnnotation.m ,如下所示
#import "MapAnnotation.h"@implementation MapAnnotation-(id)initWithTitle:(NSString *)title andCoordinate: (CLLocationCoordinate2D)coordinate2d{ self.title = title; self.coordinate =coordinate2d; return self;}@end
10.更新ViewController.h ,如下所示
#import <UIKit/UIKit.h>#import <MapKit/MapKit.h>#import <CoreLocation/CoreLocation.h>@interface ViewController : UIViewController<MKMapViewDelegate>{ MKMapView *mapView;}@end
11.更新ViewController.m ,如下所示
#import "ViewController.h"#import "MapAnnotation.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; mapView = [[MKMapView alloc]initWithFrame: CGRectMake(10, 100, 300, 300)]; mapView.delegate = self; mapView.centerCoordinate = CLLocationCoordinate2DMake(37.32, -122.03); mapView.mapType = MKMapTypeHybrid; CLLocationCoordinate2D location; location.latitude = (double) 37.332768; location.longitude = (double) -122.030039; // Add the annotation to our map view MapAnnotation *newAnnotation = [[MapAnnotation alloc] initWithTitle:@"Apple Head quaters" andCoordinate:location]; [mapView addAnnotation:newAnnotation]; CLLocationCoordinate2D location2; location2.latitude = (double) 37.35239; location2.longitude = (double) -122.025919; MapAnnotation *newAnnotation2 = [[MapAnnotation alloc] initWithTitle:@"Test annotation" andCoordinate:location2]; [mapView addAnnotation:newAnnotation2]; [self.view addSubview:mapView];}// When a map annotation point is added, zoom to it (1500 range)- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views{ MKAnnotationView *annotationView = [views objectAtIndex:0]; id <MKAnnotation> mp = [annotationView annotation]; MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance ([mp coordinate], 1500, 1500); [mv setRegion:region animated:YES]; [mv selectAnnotation:mp animated:YES];}- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
运行应用程序时,输出结果如下
当我们向上滚动地图时,输出结果如下
相机是移动设备的共同特点之一,我们能够使用相机拍摄图片,并在应用程序里调用它,而且相机的使用很简单。
1、创建一个简单的View based application
2、在ViewController.xib中添加一个button (按钮),并为该按钮创建IBAction
3、添加一个 image view (图像视图),并创建一个名为imageView的IBOutlet
4、ViewController.h文件代码如下所示:
#import <UIKit/UIKit.h>@interface ViewController : UIViewController<UIImagePickerControllerDelegate>{ UIImagePickerController *imagePicker; IBOutlet UIImageView *imageView; }- (IBAction)showCamera:(id)sender;@end
5、修改ViewController.m,如下所示:
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; }- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}- (IBAction)showCamera:(id)sender { imagePicker.allowsEditing = YES; if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) { imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; } else{ imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; } [self presentModalViewController:imagePicker animated:YES];}-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage]; if (image == nil) { image = [info objectForKey:UIImagePickerControllerOriginalImage]; } imageView.image = image; }-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ [self dismissModalViewControllerAnimated:YES];}@end
运行该应用程序并单击显示相机按钮时,我们就会获得下面的输出
只要拍照之后,就可以通过移动和缩放对图片进行编辑,如下所示。
文件处理不能直观的通过应用程序来解释,我们可以从以下实例来了解IOS的文件处理。
IOS中对文件的操作. 因为应用是在沙箱(sandbox)中的,在文件读写权限上受到限制,只能在几个目录下读写文件。
下面列出了用于访问和操作文件的方法的列表。
以下实例你必须替换FilePath1、FilePath和FilePath字符串为完整的文件路径,以获得所需的操作。
检查文件是否存在
NSFileManager *fileManager = [NSFileManager defaultManager]; //Get documents directory NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectoryPath = [directoryPaths objectAtIndex:0]; if ([fileManager fileExistsAtPath:@""]==YES) { NSLog(@"File exists"); }
比较两个文件的内容
if ([fileManager contentsEqualAtPath:@"FilePath1" andPath:@" FilePath2"]) { NSLog(@"Same content"); }
检查是否可写、可读、可执行文件
if ([fileManager isWritableFileAtPath:@"FilePath"]) { NSLog(@"isWritable"); } if ([fileManager isReadableFileAtPath:@"FilePath"]) { NSLog(@"isReadable"); } if ( [fileManager isExecutableFileAtPath:@"FilePath"]){ NSLog(@"is Executable"); }
移动文件
if([fileManager moveItemAtPath:@"FilePath1" toPath:@"FilePath2" error:NULL]){ NSLog(@"Moved successfully"); }
复制文件
if ([fileManager copyItemAtPath:@"FilePath1" toPath:@"FilePath2" error:NULL]) { NSLog(@"Copied successfully"); }
删除文件
if ([fileManager removeItemAtPath:@"FilePath" error:NULL]) { NSLog(@"Removed successfully"); }
读取文件
NSData *data = [fileManager contentsAtPath:@"Path"];
写入文件
[fileManager createFileAtPath:@"" contents:data attributes:nil];