項目功能大全,讓你的項目一天搞定

今天有人問我如何開始寫一個項目,不由回憶起本身寫第一個項目的時候,到如今,忽然感受本身寫的好多都是在重複,有些感想,特此寫下這篇文章,給想入這行的新手們一些參考git

1.寫項目以前首先咱們要肯定需求,明確項目須要實現哪些功能(吐槽下:好多項目的大部分功能都是同樣的)github

2,美工,後臺啥的我都直不一一說了狀況都不同sql

廢話不說了直接開寫程序
很重要(1)首先咱們要肯定明確開發須要的框架,一個好的框架可讓咱們輕鬆不少數據庫

框架能夠本身寫,也能夠從網上找,多對比一下會有驚喜的
頁面
(1)通常每一個詳情頁面都有相應的導航欄;若是有直接參考(見導航Deno,直接輸入圖片網址或者本地圖片,設置座標一鍵搞定);若是沒有直接跳過
(2)而後就到了圖文佈局了:(推薦xib或storyboard)強大快速(尤爲項目比較急的時候更是不二選擇);不熟練的話那就老實的算座標,佈局吧!這個狀況太多,通常難度也不大,費點心基本均可以搞定(我在這裏就不詳細說了。)
我這裏就按功能說了(不須要就直接跳過)json

功能:搜索數組

第一種搜索:UISearchBar 遵照協議
//將要進入編輯模式調用緩存

 

 

  • (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
    //顯示cancel 按鈕
    [searchBar setShowsCancelButton:YES animated:YES];
    return YES;
    }

     


//將要退出編輯模式調用服務器

  • 1 (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
    2 請把代碼粘貼在這裏
    3 //隱藏cancel 按鈕
    4 [searchBar setShowsCancelButton:NO animated:YES];
    5 return YES;
    6 }

     

// 點擊 搜索按鈕的時候調用微信

  •  1 (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { 2 //寫入搜索內容(根據須要進行搜索) 3 } 

//點擊cancel 被調用網絡

  • 1 (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    2 //清空內容
    3 searchBar.text = @"";
    4 [searchBar resignFirstResponder];//收鍵盤
    5 }

     

  • 第二種搜索

  • iOS8新出的感受很強大,你們之後儘可能都用它吧,緊跟版本呀!
    UISearchController :它的其中一個屬性就是searchBar
    須要先設置它的搜索結果視圖
    //nil爲和當前視圖總用一個視圖
    self.searchVC = [[UISearchController alloc] initWithSearchResultsController:nil];
    //若是不須要刻意再建立一個如:
    UITableViewController *tableVC = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
    
    tableVC.tableView.delegate = self;
    tableVC.tableView.dataSource = self;
    [tableVC.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
    self.searchVC = [[UISearchController alloc] initWithSearchResultsController:tableVC];
    
    注意須要兩個協議
    //搜索協議
    delegate
    //更新搜索內容的代理
    searchResultsUpdater
    //必需要加上 自適應才能顯示 搜索條
    [self.searchVC.searchBar sizeToFit];
    UISearchResultsUpdating 協議
    
    (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
    NSLog(@"searchBar 更新內容");
    //搜索內容
    //檢索推薦謂詞檢索,快準狠有沒有!詳細的去百度吧度娘威武!
    
    //最後搜索數據源變了 ->讓搜索控制器 內部的結果視圖控制器的tableView的刷新
    UITableViewController tableVC = (UITableViewController )searchController.searchResultsController;
    [tableVC.tableView reloadData];
    }
    
    (void)willPresentSearchController:(UISearchController *)searchController {
    NSLog(@"searchController 將要 顯示");
    }
    
    (void)didPresentSearchController:(UISearchController *)searchController {
    NSLog(@"searchController 已經 顯示");
    }
    (void)willDismissSearchController:(UISearchController *)searchController {
    NSLog(@"searchController 將要 消失");
    }
    
    (void)didDismissSearchController:(UISearchController )searchController {
    NSLog(@"searchController 已經 消失");
    }
    !!若是須要頁面跳轉
    在進行頁面跳轉的時候要注意如今有兩個視圖呀須要區分開
    UIViewController vc = nil;
    //self.presentedViewController獲取已經模態跳轉上冊的視圖控制器,若是dismiss 以後 這個值會變成nil
    if (self.presentedViewController) {
    
      //判斷一下 當前視圖控制器有沒有 模態跳轉 的視圖,若是有 那麼 作另一個模態跳轉的時候 應該用 上一個已經模態跳轉的控制器進行 模態跳轉下一個
      vc = self.presentedViewController;
    }else {
    
      vc = self;
    }
    //模態跳轉
    [vc presentViewController:alert animated:YES completion:nil];
    
    下載
    首先判斷是否已經下載過,而後告知服務器從哪裏下載,
    (1)下載前須要先肯定路徑
    獲取文件在沙盒中Documents下的全路徑
    //咱們把url做爲文件名字-》可是url 中可能存在一些非法字符不能做爲文件名,這時咱們能夠用md5 對文件名進行加密 產生一個惟一的字符串 (十六進制的數字+A-F表示),這樣就能夠保證文件名不出現非法字符
    NSString fileName = [url MD5Hash];//MD5
    //獲取Documents
    NSString docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
    //拼接路徑
    NSString filePath = [docPath stringByAppendingPathComponent:fileName];
    NSLog(@"path:%@",filePath);
    *這裏須要用到OC文件管理的知識!
    //建立文件(首先檢測有沒有存在,若是沒有在建立)
    if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
    //檢測文件是否存在
    //不存在那麼要建立
    //NSFileManager 文件管理句柄
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
    }
    //若是已存在獲取已近下載的大小,若是不存在那麼大小爲0;
    NSDictionary fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
    //保存已經下載文件的大小
    self.loadedFileSize = fileSize;
    //下載前須要打開文件
    self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
    *(若是服務器支持可變斷點續傳能夠照用,若是不支持請忽略 頭域)
    //把文件大小告知服務器
    //建立可變請求 增長請求頭
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    //增長頭域 告知服務器 從 哪一個字節以後開始下載(不瞭解頭域的仍是那句話百度),不支持頭域的能夠直接跳過
    [request addValue:[NSString stringWithFormat:@"bytes=%llu-",fileSize] forHTTPHeaderField:@"Range"];
    //建立請求鏈接 開始異步下載
    _httpRequest = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    NSURLConnectionDataDelegate
    //接收服務器響應
    
    (void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response {
    在這裏咱們能夠計算文件的總大小,獲取數據的類型 : httpResponse.MIMEType ,數據的大小: NSHTTPURLResponse httpResponse = (NSHTTPURLResponse )response
    NSLog(@"url:%@",httpResponse.URL.absoluteString);
    //計算文件總大小 = 已經下載的+服務器將要發的
    ( self.loadedFileSize和上面關聯着 數據是一段一段下載的)
    self.totalFileSize = self.loadedFileSize+httpResponse.expectedContentLength;
    }
    //接收數據過程 一段一段接收
    (void)connection:(NSURLConnection )connection didReceiveData:(NSData )data {
    //都是OC文件管理的知識,我就不細說了吧
    //下載一段 寫一段數據
    //先把文件偏移量定位到文件尾
    [_fileHandle seekToEndOfFile];
    //寫文件
    [_fileHandle writeData:data];
    //當即同步到磁盤
    [_fileHandle synchronizeFile];
    //記錄已經下載數據大小
    self.loadedFileSize += data.length
    }
    //下載完成必定要關閉呀
    (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [self stopDownload];//中止下載
    }
    //下載失敗也要關閉呀
    (void)connection:(NSURLConnection )connection didFailWithError:(NSError )error {
    [self stopDownload];
    }
    (void)stopDownload {
    if (_httpRequest) {
      [_httpRequest cancel];
      _httpRequest = nil;
    }
    [_fileHandle closeFile];//關閉文件
    }
    收藏(關注)
    這和數據庫有關聯(數據庫下面我會說的,不懂得也能夠先看後面的數據庫)
    點擊收藏按鈕的時候至關於在數據庫裏面增長了一條數據
    和關注按鈕基本同樣,有時候只是表現形似不一樣罷了本質都是同樣
    這裏我用的是DBManager
    //關於數據庫的方法,本身寫的,就是這裏面記錄的都是收藏過得數據
    //獲取全部的收藏過得數據,放在數組裏
    self.favoriteArr = [[DBManager sharedManager]fetchall];
    而後遍歷數組獲取相關圖片的的URL下載圖片
    for (int i = 0; i<_self.favoriteArr.count; i++) {
    AppModel model = _favoriteArr;
    //我這裏建個button 來顯示收藏(具體問題具體分析說白了就是把你收藏的東西展示出來)圖片下載用的是SDimage第三方庫
    UIButton btn = [UIButton buttonWithType:UIButtonTypeCustom];
    [btn sd_setImageWithURL:[NSURL URLWithString:model.iconUrl] forState:UIControlStateNormal placeholderImage:[UIImage imageNamed: @"account_candou"]];
    。
    。
    。
    }
    登陸和註冊(每一個App必備的功能)
    分爲 ,自身登陸註冊(本身起的名字知道大概意思就好了哈,別在乎哈) 和 第三方登陸(微博,QQ,微信,等外國的不經常使用,基本就是那幾個社交的,忘了還有人人(話說沒多少人用了吧),第三方遵循的基本原則:那我的多就用那個)
    主要說下自身登陸註冊
    大多數登陸和註冊都用的是post請求{這裏須要咱們和作服務器的協調好,登錄成功,登陸失敗返回什麼
    咱們根據這些來提示用戶是否登錄成功,!
    若是用戶登陸成功咱們須要記錄用戶登陸成功這個狀態,以防止用戶屢次登陸,重複登陸
    這時咱們須要定義一個全局變量
    在登陸成功後記錄登陸狀態
    如
    extern:引入外部變量
    extern BOOL isLogin;
    isLogin=YES;
    
    在其餘頁面再須要登陸的先判斷登陸狀態,若是爲YES就不須要在登錄了,若是沒有提示用戶須要登陸後才能夠進入
    }
    第三方登陸直接到開放平臺下demo;
    
    清除緩存
    
    這裏我用的SDimage庫的
    
    import "UIImageView+WebCache.h"
    -(double)getCachesSize
    {
    //SDimage緩存
    NSInteger sdfileSize=[[SDImageCache sharedImageCache]getSize]; NSStringcaches=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
    NSStringmycacehs=[caches stringByAppendingPathComponent:@"MyCaches"];
    NSDirectoryEnumeratorenumor=[[NSFileManager defaultManager]enumeratorAtPath:mycacehs];
    NSUInteger mysize=0;
    for (NSString filename in enumor) {
    NSStringfilepath=[mycacehs stringByAppendingPathComponent:filename];
    NSDictionaryfiledict=[[NSFileManager defaultManager]attributesOfItemAtPath:filepath error:nil];
    //自身緩存
    mysize+=filedict.fileSize;
    }
    return (mysize+sdfileSize)/1024.0/1024.0;
    }
    分享
    :(系統的和第三方的: 第三方的推薦友盟(簡單呀兩句話sdk:直接抄不用改省事哈哈,不過就一個微博能夠用,若是想用QQ,微信,等,自有你們蛋疼的去對着文檔來吧,))
    系統的:
    協議:MFMessageComposeViewControllerDelegate(信息),MFMailComposeViewControllerDelegate(郵箱)
    1(信息)
    
    //須要真機,虛擬機沒效果
    if ([MFMessageComposeViewController canSendText]) {
    //檢測 當前應用 是否支持短信功能
    //支持的話 建立 具備短信模塊的界面
    MFMessageComposeViewController *message = [[MFMessageComposeViewController alloc] init];
    //設置聯繫人 (能夠羣發)
    message.recipients = @[@"10086",@"10011"];
    //設置短信的內容
    message.body = [NSString stringWithFormat:@"快來下載,這裏有驚喜:%@「,@「網址」];
    message.messageComposeDelegate = self;
    //模態跳轉(內部有導航)
    [self presentViewController:message animated:YES completion:nil];
    
    }
    //協議
    
    (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
    switch (result) {
    
      case MessageComposeResultCancelled:
      {
          NSLog(@"取消");
      }
          break;
      case MessageComposeResultSent:
      {
          NSLog(@"短信已發送");
      }
          break;
      case MessageComposeResultFailed:
      {
          NSLog(@"短信失敗");
      }
          break;
    
      default:
          break;
    }
    //最後要模態跳轉返回
    [controller dismissViewControllerAnimated:YES completion:nil];
    }
    (2)郵箱
    if ([MFMailComposeViewController canSendMail]) {
    
              //檢測是否支持郵箱功能
              //若是支持 建立界面
              MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
              //設置聯繫人
              [mail setToRecipients:@[@"xxxxx@qq.com」,@「zzzz@163.com"]];
              //設置抄送
              [mail setCcRecipients:@[@"xxx@sina.com"]];
              //設置標題
              [mail setSubject:@"分享愛限免應用"];
              //設置內容
              NSString *str = [NSString stringWithFormat:@"點擊有驚喜:%@「,@「網址」];
              //第二個參數 是否以HTML格式
              [mail setMessageBody:str isHTML:YES];
    
              //添加附件
              NSData *data = UIImagePNGRepresentation([UIImage  imageNamed: @"account_candou"]);
              //第一個參數 文件二進制  2 文件的類型 3  文件的名字
              [mail addAttachmentData:data mimeType:@"image/png" fileName:@"account_candou"];
    
              //設置代理
              mail.mailComposeDelegate = self;
              //模態跳轉
              [self presentViewController:mail animated:YES completion:nil];
          }
    //協議
    
    (void)mailComposeController:(MFMailComposeViewController )controller didFinishWithResult:(MFMailComposeResult)result error:(NSError )error {
    switch (result) {
    
      case MFMailComposeResultCancelled:
          NSLog(@"郵件取消");
          break;
      case MFMailComposeResultSaved:
          NSLog(@"郵件保存");
          break;
      case MFMailComposeResultSent:
          NSLog(@"郵件發送");
          break;
      case MFMailComposeResultFailed:
          NSLog(@"郵件失敗");
          break;
    
      default:
          break;
    }
    //模態跳轉返回
    [self dismissViewControllerAnimated:YES completion:nil];
    }
    //友盟的(不懂能夠看官網)創建使用UM的 ,系統的太坑了,在我們這沒人用呀
    //協議
    UMSocialUIDelegate
    [UMSocialSnsService presentSnsIconSheetView:self appKey:@"507fcab25270157b37000010" shareText:str shareImage:[UIImage imageNamed: @"account_candou"] shareToSnsNames:[NSArray arrayWithObjects:UMShareToSina,UMShareToSms,UMShareToEmail,UMShareToWechatTimeline,nil] delegate:self];(寫了這麼多也就前三個有用微信須要本身去註冊)
    在appdelgete.m中(其餘的,哎都是淚看文檔把,你妹的呀)
    //初始化UM
    
    (void)initUM {
    
    //初始化
    [UMSocialData setAppKey:@"507fcab25270157b37000010"];
    }
    地圖
    又到了都是淚的地方,文檔走起吧,大蘋果太渣
    推薦百度,高德,騰訊(百度最好,可是那啥註冊一把淚呀)
    (1)定位:
    //1.頭文件
    
    import <CoreLocation/CoreLocation.h>
    協議 CLLocationManagerDelegate
    //必需要強引用 在定位以前不能釋放
    @property (nonatomic,strong) CLLocationManager *manager;
    kCLLocationAccuracyBestForNavigation -->最好的精度 用於導航
    kCLLocationAccuracyBest;//精度高的
    kCLLocationAccuracyNearestTenMeters; 10m
    kCLLocationAccuracyHundredMeters; 100m
    kCLLocationAccuracyKilometer; 1000m
    kCLLocationAccuracyThreeKilometers; 3000m
    //精度越高 越耗電
    
    (void)initLocationManager {
    //用的時候才建立 懶加載
    if (!self.manager) {
    
      //實例化 管理器
      self.manager = [[CLLocationManager alloc] init];
      //設置精度類型
      self.manager.desiredAccuracy = kCLLocationAccuracyBest;
      //設置 精度的大小
      self.manager.distanceFilter = 10;
      //獲取定位的數據 必需要設置代理
      self.manager.delegate = self;
      //iOS8以後 必需要向用戶申請受權
      /*
       1.在Info.plist中 添加選項
          Privacy - Location Usage Description(可選)
          NSLocationAlwaysUsageDescription(和代碼要對應)
          或者
          NSLocationWhenInUseUsageDescription(代碼要對應)
       2.在代碼中 添加
          [self.manager requestAlwaysAuthorization];
          或者
          [self.manager requestWhenInUseAuthorization];
       */
    
      double v = [UIDevice currentDevice].systemVersion.doubleValue;
      if (v >= 8.0) {//判斷版本
          //設置一個就能夠
          //始終容許受權打開定位 (先後臺都容許)
          [self.manager requestAlwaysAuthorization];
          //使用的時候容許 (前臺容許)
          //[self.manager requestWhenInUseAuthorization];//
          //容許以後 第一次 會彈出一個警告框 選擇容許
      }
      //下面的條件編譯也能夠 判斷當前系統 版本
    ifdef IPHONE_8_0 //若是定義過這個宏IPHONE_8_0,iOS8.0以後就會定義宏__IPHONE_8_0
    endif
    }
    }
    //開始定位
    
    (void)startLocation:(UIBarButtonItem *)item {
    //判斷是否具有定位功能
    if ([CLLocationManager locationServicesEnabled]) {
      //懶加載管理器
      [self initLocationManager];
      //開始定位
      [self.manager startUpdatingLocation];
    }
    }
    //中止定位
    (void)stopLocation:(UIBarButtonItem *)item {
    [self.manager stopUpdatingLocation];
    }
    定位協議
    //當定位的位置 發生改變的時候 一會一直調用
    //會把定位的地理位置 傳入
    //locations 存放的就是地理位置
    //數組中就一個元素
    //
    (void)locationManager:(CLLocationManager )manager didUpdateLocations:(NSArray )locations {
    if (locations.count) {
      //獲取定位 位置
      CLLocation *location = [locations lastObject];
      //獲得經緯度
      CLLocationCoordinate2D coordinate = location.coordinate;
      //打印經緯度
      NSLog(@"location:%f %f",coordinate.longitude,coordinate.latitude);
      //地理反編碼
    //把經緯度裝化爲具體的地址
    if 0
      [self reverseGeocoderWithBaidu:coordinate];
    else
      [self reverseGeocoderWithSystem:location];
    endif
    }
    }
    //百度的
    //須要OCJson解析
    
    (void)reverseGeocoderWithBaidu:(CLLocationCoordinate2D)coordinate {
    //用多線程 異步下載
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
      NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:kPathUrl,coordinate.latitude,coordinate.longitude]]];
      //json解析
      NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
      NSDictionary *resultDict = dict[@"result"];
      NSLog(@"address:%@",resultDict[@"formatted_address"]);//獲取地址
    });
    }
    //系統 地理反編碼
    
    (void)reverseGeocoderWithSystem:(CLLocation)location {
    //建立對象
    CLGeocoder geocoder = [[CLGeocoder alloc] init];
    //根據location內部的經緯度 進行 地理反編碼
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray placemarks, NSError error) {
      //placemarks  咱們要的反編碼信息
      for (CLPlacemark *placemark in placemarks) {
          NSLog(@"country:%@",placemark.country);
          NSLog(@"name:%@",placemark.name);
          //遍歷地址字典
          for (NSString *key in placemark.addressDictionary) {
              NSLog(@"%@",placemark.addressDictionary[key]);
          }
      }
    }];
    }
    
    (void)locationManager:(CLLocationManager )manager didFailWithError:(NSError )error {
    NSLog(@"定位失敗");
    }
    (2)導航:在定位的基礎的延伸
    (3)查詢:在定位的基礎的延伸
    (4)地圖:
    
    我把系統的說了,其餘的百度和高德,騰訊的本身下()
    和定位很相似
    
    import <MapKit/MapKit.h>
    協議
    MKMapViewDelegate
    @property (nonatomic, strong) MKMapView *mapView;//地圖
    (void)initMapView {
    [self initManager];//須要定位 就調用
    
    //實例化 地圖
    self.mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
    self.mapView.mapType = MKMapTypeStandard;
    //設置地圖顯示的 區域 (給一箇中心位置)
    // 給一個 經緯度 和 縮放比例(0.01---0.05)
    //34.77274892, 113.67591140
    self.mapView.region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(34.77274892, 113.67591140),MKCoordinateSpanMake(0.01, 0.01));
    //是否顯示 用戶位置
    self.mapView.showsUserLocation = YES;
    
    //設置代理
    self.mapView.delegate = self;//能夠操做點標註
    
    //粘貼地圖
    [self.view addSubview:self.mapView];
    
    //增長大頭針(須要就建立不須要能夠無視)
    [self createAnnotation];
    }
    
    協議方法
    
    (MKAnnotationView )mapView:(MKMapView )mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
    //判斷是哪一類點標註數據
    //建立 點標註視圖 (採用複用機制)
    //隊列獲取空閒的
    MKPinAnnotationView pinView = (MKPinAnnotationView )[mapView dequeueReusableAnnotationViewWithIdentifier:@"MKPinAnnotationView"];
    if (pinView == nil) {
    //沒有那麼建立新的
    pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MKPinAnnotationView"];
    }
    //設置屬性(不須要的能夠不設置)
    //是否顯示氣泡
    pinView.canShowCallout = YES;
    //是否有掉落的動畫
    pinView.animatesDrop = YES;//(點標註視圖子類MKPinAnnotationView才能夠設置)
    //設置大頭針視圖的顏色 紅 綠 紫三種
    pinView.pinColor = MKPinAnnotationColorPurple;
    
        //設置氣泡的左右側附件
        UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
        redView.backgroundColor = [UIColor redColor];
        pinView.leftCalloutAccessoryView = redView;
    
        UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoLight];
        button.frame = CGRectMake(0, 0, 30, 30);
        //氣泡附件 若是是UIControl的子類 不須要再增長事件,有一個協議的方法能夠替代
        //[button addTarget:<#(id)#> action:<#(SEL)#> forControlEvents:<#(UIControlEvents)#>];
        pinView.rightCalloutAccessoryView = button;
        return pinView;//返回對象地址
    }
    }
    若是須要的還能夠添加手勢
    
    (void)createLongPress {
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
    [self.mapView addGestureRecognizer: longPress];
    }
    根據手勢作出不一樣的調用
    (void)longPress:(UILongPressGestureRecognizer *)press {
    }
    數據庫
    sqlite(通常咱們不直接向數據庫進行操做,使用 第3方庫來操做數據庫,方便快速,但不能認爲這些庫就能存儲數據,簡單點理解這玩意就是中介)
    經常使用的有FMDB(開源庫) coredata(官方系統庫)
    經常使用的數據庫操做,增刪改查
    首先導入第三方庫FMDB
    封裝一個類來管理數據庫
    方法:
    代碼操做數據庫 用fmdb 第三庫操做 sqlite
    fmdb 就是 經過對C語言的底層函數封裝 對 數據庫進行建立 增刪改查數據
    
    步驟
    1.導入fmdb
    2.導入libsqlite3.dylib
    3.導入頭文件 #import "FMDatabase.h"
    
    建立 數據庫
    4.1打開數據庫 建立表
    4.2 增刪改查數據 代碼執行sql 語句
    //導入頭文件
    import "FMDatabase.h"
    建立數據庫
    (void)createDataBase {
    //沙盒路徑
    NSString docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    //拼接 數據庫的路徑後面的數據庫的名字
    NSString dataPath = [docPath stringByAppendingPathComponent:@"myData.sqlite"];
    //實例化一個 fmdb 對象
    NSLog(@"%@",dataPath);
    _database = [[FMDatabase alloc] initWithPath:dataPath];
    
    //若是打開成功 返回yes
    //調用open 的時候 若是數據庫不存在那麼就會先建立再打開,若是存在直接打開
    if ([_database open]) {//打開數據庫
    
      //打開成功以後建立表
      [self createTable];
    }else{
    
      NSLog(@"open error:%@",[_database lastErrorMessage]);//最近一次錯誤
    }
    //數據庫 通常 只打開一次 這樣能夠提升效率
    }
    建立表格
    //其實的在數據庫裏面建立表是同樣只不過用庫來代建立方便(和用中介找房子同樣的)
    //user是表名(後面的表的屬性)
    
    (void)createTable {
    NSString *sql = @"CREATE TABLE if not exists user (serial integer Primary Key Autoincrement,num integer,name Varchar(256),mydate datetime,headimage blob)";
    //執行 sql 語句 成功返回yes 失敗返回no
    BOOL isSuccess = [_database executeUpdate:sql];
    if (!isSuccess) {
      NSLog(@"create table error:%@",_database.lastErrorMessage);
    }
    }
    //增長數據
    (void)insertData {
    NSInteger num = arc4random()%69+1;
    NSString name = [NSString stringWithFormat:@"xiaohong%u",arc4random()%100];
    //時間
    NSDate date = [NSDate date];
    
    //圖片要存成二進制
    NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed: @"0"]);
    //要用 ? 佔位符 在sql 中 ? 表示的是對象的佔位符
    // ? 對應的必須是一個 OC的對象的地址
    
    //增長 sql 語句
    NSString *sql = @"insert into user(num,name,mydate,headimage) values (?,?,?,?)";
    
    //執行sql
    BOOL isS = [_database executeUpdate:sql,@(num),name,date,imageData];
    if (!isS) {
    
      NSLog(@"insert into error :%@",_database.lastErrorMessage);
    }
    }
    //查詢
    
    (void)fetchAllData{
    //1.sql
    NSString sql = @"select num,name,mydate,headimage from user";
    //2.執行
    //會返回一個結果集合 查找的結果都在 FMResultSet中
    FMResultSet rs = [_database executeQuery:sql];
    //遍歷集合
    while ([rs next]) {//表示 FMResultSet中還有沒有記錄
      NSInteger num = [rs intForColumnIndex:0];//根據字段索引獲取值
      NSInteger num2 = [rs intForColumn:@"num"];//根據字段名字獲取值
      NSLog(@"num:%ld num2:%ld",num,num2);
      NSLog(@"name:%@",[rs stringForColumn:@"name"]);
      NSLog(@"date:%@",[rs dateForColumn:@"mydate"]);
      NSLog(@"image_length:%ld",[rs dataForColumn:@"headimage"].length);
      NSLog(@"-------------------------------");
      //[rs objectForColumnName:<#(NSString *)#>];//通用
    }
    //第一循環 遍歷第0條記錄
    //第二循環 1
    //...
    //直到最後沒有了記錄 循環退出
    }
    //更新數據
    -(void)updateData
    {
    NSStringsql=@"update user name=? where num<50 ";
    if ([_database executeUpdate:sql,@"小紅" ]) {
    NSLog(@"updata error:%@",_database.lastErrorMessage);
    }
    }
    //刪除數據
    -(void)deletedatawithNUm:(NSInteger)num
    {
    NSStringsql=@"delete from user where num=?";
    if ([_database executeUpdate:sql,@(num)]) {
    NSLog(@"%@",_database.lastErrorMessage);
    }
    }
    coredata蘋果官方的效果棒棒噠,也很好用
    
    首先先右鍵—》newfile—> (iOS )core data—>DataModel 完成後會有類名.xcdatamodel文件,可視化操做,建立表(注意改下表名字,默認的有可能關聯不上),而後在表裏面添加屬性,完成後右鍵—》newfile—> (iOS )core data—>NSManagerObject subclass ,而後和你的表關聯一下model層就建立出來了,
    下面就是封裝一個類來專門管理coredata,方便咱們對數據庫盡心操做
    導入頭文件
    
    import <CoreData/CoreData.h>
    /設計一個單例類 管理數據庫
    @interface CoreDataManager : NSObject
    //非標準單例
    
    (instancetype)defaultManager;
    //上下文管理對象
    @property (nonatomic,strong) NSManagedObjectContext *context;
    
    //增刪改查
    //增長一個數據
    
    (void)insertDataWithName:(NSString *)name age:(int)age;
    //根據名字刪除
    
    (void)deleteDataWithName:(NSString *)name;
    //修改數據 根據名字修改年齡
    
    (void)updateDataWithName:(NSString *)name age:(int)age;
    //查詢
    //查詢全部的數據
    
    (NSArray *)fetchAllData;
    //根據名字查找
    
    (NSArray )fetchDataWithName:(NSString )name;
    實現方法:
    //(建立單例類的方法網上有好多)
    
    (instancetype)defaultManager {
    static CoreDataManager *manager = nil;
    
    @synchronized(self) {
    
      manager = [[self alloc] init];
    }
    return manager;
    }
    //初始化準備工做
    //1.導入頭文件 CoreData/CoreData.h
    //2.建立一個 一個數據模型文件(和數據庫中的表相似),裏面建立一些數據模型(設計屬性)
    //3.設計 一個數據模型類(根據數據模型文件)
    //術語不明白的度娘走起(我就不嘮叨了)
    
    (instancetype)init {
    if (self = [super init]) {
    
      //1.將數據模型文件中的 的模型 放入 modelFile 指向的 對象中
      //關聯數據模型
       NSManagedObjectModel *modelFile = [NSManagedObjectModel mergedModelFromBundles:nil];
    
      //2.設置 存儲 協調器  (協調 底層和上層)
      //2.1讓 協調器 和 modelFile產生關聯
      NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:modelFile];
    
      //2.2設置數據庫文件的路徑
      NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents/Mydata.sqlite"];
      NSError *error = nil;
      //2.3設置 存儲方式 根據路徑建立 數據庫文件
      ///將coreData數據  映射到數據庫
    
      NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:path] options:nil error:&error];
      if (!store) {
          //建立 失敗
          NSLog(@"creat store falied:%@",error.localizedDescription);
          return nil;
      }
    
      //3.託管對象 /上下文管理對象
      self.context = [[NSManagedObjectContext alloc] init];
      //託管對象 和 協調器 產生 關聯
      self.context.persistentStoreCoordinator = coordinator;
      //_context 對數據庫 進行增刪改查
    }
    return self;
    }
    下面就是增刪改查了
    //增長一個數據
    
    (void)insertDataWithName:(NSString *)name age:(int)age {
    //1.給_context 操做的數據 增長一個UserModel實例對象
    
    //用 NSEntityDescription來增長
    UserModel model = (UserModel )[NSEntityDescription insertNewObjectForEntityForName:@"UserModel" inManagedObjectContext:self.context];
    model.name = name;
    model.age = @(age);
    model.fName = [name substringToIndex:1];
    
    //保存數據
    [self saveDataWithType:@"addData"];
    }
    
    (void)saveDataWithType:(NSString )type {
    NSError error = nil;
    //回寫 保存到數據庫文件
    if (![self.context save:&error]) {
      //保存失敗
      NSLog(@"%@:%@",type,error.localizedDescription);
    }
    }
    //根據名字刪除
    (void)deleteDataWithName:(NSString )name {
    //根據名字 找到對象
    NSArray arr = [self fetchDataWithName:name];
    //遍歷數組
    for (UserModel *model in arr) {
      [self.context deleteObject:model];
    }
    //保存數據
    [self saveDataWithType:@"deleteData"];
    }
    //修改數據 根據名字修改年齡
    (void)updateDataWithName:(NSString )name age:(int)age{
    //1.根據名字 找到對象
    NSArray arr = [self fetchDataWithName:name];
    //2.遍歷數組
    for (UserModel *model in arr) {
      model.age = @(age);
    }
    //3.保存數據
    [self saveDataWithType:@"updateData"];
    }
    //查詢
    //查詢全部的數據
    
    (NSArray *)fetchAllData {
    return [self fetchDataWithName:nil];
    }
    根據名字 在數據庫中 查找 數據模型對象
    //根據名字查找
    (NSArray )fetchDataWithName:(NSString )name {
    //1.先設置查找請求
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    //2.設置 查找的數據模型對象
    request.entity = [NSEntityDescription entityForName:@"UserModel" inManagedObjectContext:_context];
    //3.設置 謂詞 (根據條件 找要設置謂詞)
    if (name) {
    
      //name 不是nil 那麼就根據名字找 設置謂詞
      //要查詢 一個對象的 匹配的屬性 那麼須要設置謂詞
      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@",name];
      request.predicate = predicate;
    }
    //還能夠設置排序 從小到大 或者從大到小
    //按照年齡降序 的一個描述
    NSSortDescriptor sort1 = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
    //按照 name 進行 升序排列
    NSSortDescriptor sort2 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
    
    if 0
    request.sortDescriptors = @[sort1];//按照一個準則排序 age
    
    else
    //先按照 age 進行降序排 ,若是出現age 相同 那麼 再按照name 升序排序
    request.sortDescriptors = @[sort1,sort2];
    
    endif
    //不設置 謂詞 那麼找全部
    
    //5.執行 查詢請求 返回一個數組
    NSArray resultArr = [_context executeFetchRequest:request error:nil];
    return resultArr;
    }
    封裝之後直接調就好了
    二維碼(多關注點github好東西不少的)
    第三方庫ZBarSDK
    導入庫
    導入系統庫
    libz.dylib
    libicony.dylib
    QuartzCore.framework
    CoreVideo.framework
    CoreMedia.framework
    AVfoundation.framwork
    原理示例:
    二維碼編譯順序
    Zbar編譯
    須要添加AVFoundation CoreMedia CoreVideo QuartzCore libiconv
    ZCZBarViewControllervc=[[ZCZBarViewController alloc]initWithBlock:^(NSString *str, BOOL isScceed) {
    if (isScceed) {
    NSLog(@"掃描後的結果~%@",str);
    
          }
    }];
    [self presentViewController:vc animated:YES completion:nil];
    生成二維碼
    拖拽libqrencode包進入工程,注意點copy
    添加頭文件#import "QRCodeGenerator.h"
    imageView.image=[QRCodeGenerator qrImageForString:@"這個是什麼" imageSize:imageView.bounds.size.width];
    
    import "ZCZBarViewController.h"
    import "QRCodeGenerator.h"
    UIButtonbutton=[UIButton buttonWithType:UIButtonTypeSystem];
    button.frame=CGRectMake(0, 70, 100, 100);
    [button addTarget:self action:@selector(btn:) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"掃描二維碼" forState:UIControlStateNormal];
    [self.view addSubview:button];
    UIImageViewimageview=[[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 200, 200)];
    imageview.image=[QRCodeGenerator qrImageForString:@"生成二維碼" imageSize:300];
    [self.view addSubview:imageview];
    -(void)btn:(UIButton*)button
    {
    
    ZCZBarViewControllervc=[[ZCZBarViewController alloc]initWithBlock:^(NSString str, BOOL isScceed) {
    if (isScceed) {
    NSLog(@"掃描後的結果~%@",str);
    }
    }];
    [self presentViewController:vc animated:YES completion:nil];
    }
    推送
    本地推送,網絡推送,激光推送(要錢呀!屌絲傷不起)
    網絡推送:
    應用場景
    提醒業務,好比一些秀場,女主播能夠通知他們的土豪(好比我),趕忙來撒錢
    天天晚上8點影視劇的推送
    小說更新
    遊戲活動推送等
    //在這個方法裏面寫
    
    (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
    if ([[[UIDevice currentDevice]systemVersion]floatValue]>=8.0) {
      [[UIApplication sharedApplication]registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge) categories:nil]];
      //開啓通知
      [[UIApplication sharedApplication]registerForRemoteNotifications];
    }
    }
    //當咱們接到通知以後,如何去處理,首先去處理一個標識
    -(void)application:(UIApplication )application didRegisterForRemoteNotificationsWithDeviceToken:(NSData )deviceToken
    {
    //咱們首先獲取一個token值,至關於咱們用的QQ,須要一個QQ號碼,那麼這個QQ是誰,是蘋果服務器,咱們本身經過本身的設備向蘋果服務器發送一個請求,告訴他們咱們應用的一個標示,做爲他們的聯繫
    //獲取token須要進行處理,把這個標示發給咱們服務器端作記錄,當咱們的服務器須要給用戶發消息的時候,使用這個標示符+咱們要發送的消息給蘋果服務器,拼過會根據這個標示符發到對應的手機的裏面
    //由於在有網的狀況下,手機是一直和蘋果服務器保持者聯繫,從理論上來講蘋果能夠控制任何一臺手機的狀況下進行相關的操做
    //最明顯的就是,在有網的狀況下,你收不到任何消息,可是在有網的狀況下會彈出不少消息
    NSLog(@"%@",deviceToken );
    }
    //出錯處理
    -(void)application:(UIApplication )application didFailToRegisterForRemoteNotificationsWithError:(NSError )error
    {
    NSLog(@"%@",error);
    }
    -(void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo
    {
    //接受推到消息的是一個字典,是規定的格式
    
    }
    本地推送:
    
    (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
    }
    /建立一個本地推送
    UILocalNotificationlocal=[[UILocalNotification alloc]init];
    //設置推送內容
    local.alertBody=@「親,何時約;
    //設置聲音
    local.soundName=@"au_gameover.wav";
    //設置推送數目
    local.applicationIconBadgeNumber=1000;
    local.fireDate=[NSDate dateWithTimeIntervalSinceNow:10];
    //把推送任務增長到推送隊列中,須要注意,推送通知後,程序就算被殺掉,推送通知任然能夠運行
    //虛擬機上若是要看效果的話
    //若是要彈出推送通知,須要程序退出後臺,快捷鍵Connand+Shitf+h
    [[UIApplication sharedApplication]scheduleLocalNotification:local];
    /
    //刪除通知
    NSArraylocalArray=[UIApplication sharedApplication].scheduledLocalNotifications;
    //遍歷通知
    for (UILocalNotification notification in localArray) {
    if ([notification.alertBody isEqual:@"親,何時約"]) {
    [[UIApplication sharedApplication]cancelLocalNotification:notification];
    }
    }
    //刪除全部的通知
    // [[UIApplication sharedApplication]cancelAllLocalNotifications];
    /*
    本地推送的加入方式,好比判斷。3天沒來,每次程序啓動,把原來的舊通知,而且計算出3天后的時間
    
    */
    // NSInteger num=[UIApplication sharedApplication].applicationIconBadgeNumber;
    // num=num+1;
    // local.applicationIconBadgeNumber=num;
    */
    
    }
    //激光有Demo
    VLC(網上有教程)
    VLC集成指南
    添加libMobileVLCKit
    添加庫
    libstdc++
    libiconv
    libbz2
    Security
    QuartzCore
    CoreText
    CFnetWork
    OpenGLES
    AudioToolbox
    修改C++編譯器爲stdC++
    
    聊天(tcp-udp)
    
    (socket庫)
    
    import "AsyncSocket.h"
    協議
    AsyncSocketDelegate
    //創建發送端
    AsyncSocket sendSocket;
    //創建服務端
    AsyncSocket severSocket;
    //創建一個數組保存鏈接
    @property(nonatomic,strong)NSMutableArray * socketArray;
    
    /
    創建一個羣聊,學生向教師端發送消息,教師端顯示全部消息 /
    
    (void)CreatSocket
    {
    sendSocket=[[AsyncSocket alloc] initWithDelegate:self];
    severSocket=[[AsyncSocket alloc] initWithDelegate:self];
    //服務端綁定端口,監聽該端口接收的數據
    /
    端口最大爲65535,其中建議設置爲5000以上,另外還有一些特殊的端口,例如8080爲視頻端口,建議不要佔用 /
    [severSocket acceptOnPort:5678 error:nil];
    }
    
    (void)onSocket:(AsyncSocket )sock didAcceptNewSocket:(AsyncSocket )newSocket
    {
    //接收的一個新鏈接,這個鏈接須要保存一下,而後持續保持鏈接
    [self.socketArray addObject:newSocket];
    
    //其中-1標示持續觀察,若是設置爲300,那麼300秒之後就不在觀察
    [newSocket readDataWithTimeout:-1 tag:100];
    
    }
    //協議方法
    
    (void)onSocket:(AsyncSocket )sock didReadData:(NSData )data withTag:(long)tag
    {
    //接收到的數據
    NSString * message=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if (_textView) {
    
      //在原來的舊數據上面,追加新的數據
      _textView.text=[NSString stringWithFormat:@"%@%@",_textView.text,message];
    }
    
    [sock readDataWithTimeout:-1 tag:100];
    
    }
    
    (void)onSocket:(AsyncSocket )sock didWriteDataWithTag:(long)tag
    {
    //發送成功
    }
    //textfild協議
    //發送數據
    -(BOOL)textFieldShouldReturn:(UITextField )textField{
    if (textField.text.length>0) {
    
      // 發送數據
      if (![sendSocket isConnected]) {
          //肯定是否鏈接,若是沒有鏈接,則開始鏈接host:後面是iP地址
          [sendSocket connectToHost:@"192.168.2.7" onPort:5678 error:nil];
      }
      //當鏈接完成之後,發送數據
      //拼接數據是誰說,我但願得到當前設備的名稱
     // [[UIDevice currentDevice]systemName];該方法只有在真機上纔有效,在模擬器上無效
      NSString * message=[NSString stringWithFormat:@"%@說:%@\n",@"房騫",textField.text];
      [sendSocket writeData:[message dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:100];
    }
    return YES;
    }
    屏幕截圖
    ZCScreenShot庫
    
    此類用於屏幕截圖
    添加庫:無
    代碼示例 爲截取全屏
    [BeginImageContext beginImageContext:self.view.frame View:self.view];
    2個參數 第一個參數用於截取的範圍,第二個參數截取哪一個view上
    
    //示例代碼
    [ZCScreenShot beginImageContext:self.view.frame View:self.view];
    //第一個參數是截取圖片的範圍,第二個參數是截取的那一層
    
    import "ZCScreenShot.h"
    UIImage *image=[ZCScreenShot beginImageContext:self.view.frame View:self.view];

     

上面兩個加起來就是一個小型教學客戶端呀 

相關文章
相關標籤/搜索