iOS现场系统app使用的技术点总结

关键词

学习技术的最好方式就是做项目,边做功能边看文档,我需要这个推送那我就去看推送文档.就是这样.不是先学再去做,做中学习效率快,成就感,还到赚钱,快乐. 没项目就去看书籍,很枯燥,反正做中看文档的学习方式适合我.

FMDN离线复杂数据存储
拍照给相机显示水印
极光推送
加载html本地显示
上传照片到阿里百川


目录结构

已经App Store上架,这是一款企业级的应用.需要企业账户可以登录.前期2人搭建基础,后期个人单独完成1.0到2.0的版本升级.


iOS现场系统app使用的技术点总结_第1张图片
首页界面

iOS现场系统app使用的技术点总结_第2张图片
通用类

iOS现场系统app使用的技术点总结_第3张图片
结构

App Store上架

1.根据网上资料配置各种证书,耐心加细心.

FMDN离线复杂数据存储

数据结构如下:模型里套模型,模型里有字典,字典里有字典的结果需要离线传递到下个控制器.
参考FMDB安装使用帮助如何引入fmdb到自己xcode项目里.

iOS现场系统app使用的技术点总结_第4张图片
image.png

实现原理:
在启动页面创建数据库,如果没有就创建一张表.用到了:数据库操作.
数据库语言sql操作 学习链接.

- (void)creatProjectListTable{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString * path1 = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/projectList.sqlite"];
    NSString *documentsPath =  [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];//离线放在Documents的原因是,当更新app版本后,原来版本上的离线数据也会继续保留不丢失.不能放cache目录
    if([fileManager fileExistsAtPath:path1]){
        return;
    }else{
    //表1
    _db = [FMDatabase databaseWithPath: [documentsPath stringByAppendingPathComponent:@"projectList.sqlite"]];
    [_db open];
    
    //获得数据库
    if ([_db open]){
        //创表
        NSString *Sql = @"CREATE TABLE IF NOT EXISTS projectListTable (id integer PRIMARY KEY AUTOINCREMENT,proj_links text,proj_addr text,proj_link_name_ls text,proj_base_type text default '',proj_link_pic_max_num integer,proj_lon text,proj_company_code text,proj_import_time integer,proj_station_type text,proj_company text,proj_bu_code text,proj_code text,proj_lat text,proj_establish_time text,proj_name text,proj_link_max_distan integer,proj_tower_type text,proj_submit_time integer,proj_module_name_ls text,proj_status integer,proj_tower_height text,proj_link_id_ls integer,proj_bu_name text);";
        
        BOOL result = [_db executeUpdate:Sql];
        if (result)
        {
            NSLog(@"创建projectListTable表成功");
        }
     }
    }
    
    //表2
    NSString * path2 = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/projCacheImageList.sqlite"];
    if([fileManager fileExistsAtPath:path2]){
        return;
    }else{
    _db = [FMDatabase databaseWithPath: [documentsPath stringByAppendingPathComponent:@"projCacheImageList.sqlite"]];
    [_db open];
    
    //获得数据库
    if ([_db open]){
        NSString *Sql = @"CREATE TABLE IF NOT EXISTS projCacheImageListTable (id integer PRIMARY KEY AUTOINCREMENT,links text,proj_link_id integer,proj_link_describe text,proj_link_status integer,proj_code text,moduleCellIndex integer,iconCellIndex integer,submitTime integer,proj_link_pic_add_number integer);";
        
        BOOL result = [_db executeUpdate:Sql];
        if (result)
        {
            NSLog(@"创建projCacheImageListTable表成功");
        }
     }
    }
    
    //表3
    NSString * path3 = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/meetingsCacheList.sqlite"];//Documents
    if([fileManager fileExistsAtPath:path3]){
        return;
    }else{
        _db = [FMDatabase databaseWithPath: [documentsPath stringByAppendingPathComponent:@"meetingsCacheList.sqlite"]];
        [_db open];

        //获得数据库
        if ([_db open]){
            NSString *Sql = @"CREATE TABLE IF NOT EXISTS meetingsCacheListTable (id integer PRIMARY KEY AUTOINCREMENT,meeting_pic text,meeting_title text,meeting_end_time integer,meeting_dev_info text,meeting_id integer,meeting_company_code text,meeting_start_time integer,meeting_company_name text,meeting_submit_usercode text,meeting_addr text,meeting_status text,meeting_bu_code text,meeting_submit_userid integer,meeting_submit_time integer,meeting_submit_username text,meeting_bu_name text);";
            
            BOOL result = [_db executeUpdate:Sql];
            if (result)
            {
                NSLog(@"创建meetingsCacheListTable表成功");
            }
        }
    }
}

根据服务器返回的数组首次保存到数据库

//保存到数据库
- (void)setCacheArr:(NSMutableArray *)cacheArr{
    // 路径
    NSString *documentsPath =  [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

    _db = [FMDatabase databaseWithPath: [documentsPath stringByAppendingPathComponent:@"projectList.sqlite"]];
    [_db open];

    //获得数据库
    if ([_db open]){
        //创表
        NSString *Sql = @"CREATE TABLE IF NOT EXISTS projectListTable (id integer PRIMARY KEY AUTOINCREMENT,proj_links text,proj_addr text,proj_link_name_ls text,proj_base_type text default '',proj_link_pic_max_num integer,proj_lon text,proj_company_code text,proj_import_time integer,proj_station_type text,proj_company text,proj_bu_code text,proj_code text,proj_lat text,proj_establish_time text,proj_name text,proj_link_max_distan integer,proj_tower_type text,proj_submit_time integer,proj_module_name_ls text,proj_status integer,proj_tower_height text,proj_link_id_ls integer,proj_bu_name text);";
        
        BOOL result = [_db executeUpdate:Sql];
        if (result)
        {
            NSLog(@"创建projectListTable表成功");
        }
    }

    //插入21个
    BOOL insert = NO;
    for (int i =0; i

从数据库去取你要的数据,如下

/没网离线
- (void)getCacheArr2{
    //先创建了
     lastCacheArr = [[NSMutableArray alloc]init];
     proj_codeArr =[[NSMutableArray alloc]init];
    // 路径
    NSString *documentsPath =  [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

    _db = [FMDatabase databaseWithPath: [documentsPath stringByAppendingPathComponent:@"projectList.sqlite"]];
    [_db open];

    //获得数据库
    FMResultSet *res = [_db executeQuery:@"SELECT * FROM projectListTable"];

    if (res)
    {
        NSLog(@"取出成功");
        
    }
   
    //根据拍照时间调整会议显示顺序,保证项目顺序显示
    NSMutableArray *picTimeArr =[[NSMutableArray alloc] init];
    while ([res next]) {
        NSMutableDictionary *lastCacheIndexDic = [[NSMutableDictionary alloc] init];
        
        NSMutableArray *proj_linksArr = [CommonUtils jsonStringToArrayOrNSDictionary: [res stringForColumn:@"proj_links"]];
        [lastCacheIndexDic setObject:proj_linksArr forKey:@"proj_links"];
        
        NSString *proj_addr =  [res stringForColumn:@"proj_addr"];
        [lastCacheIndexDic setObject:proj_addr forKey:@"proj_addr"];
        
        NSString *proj_link_name_ls =  [res stringForColumn:@"proj_link_name_ls"];
        [lastCacheIndexDic setObject:proj_link_name_ls forKey:@"proj_link_name_ls"];
        
        NSString *proj_base_type =[res stringForColumn:@"proj_base_type"];
        [lastCacheIndexDic setObject:proj_base_type forKey:@"proj_base_type"];
        
        NSInteger proj_link_pic_max_num =  [res intForColumn:@"proj_link_pic_max_num"];
        [lastCacheIndexDic setObject:[NSNumber numberWithInteger:proj_link_pic_max_num] forKey:@"proj_link_pic_max_num"];
        
        NSString *proj_lon =  [res stringForColumn:@"proj_lon"];
        [lastCacheIndexDic setObject:proj_lon forKey:@"proj_lon"];
        
        NSString *proj_company_code =  [res stringForColumn:@"proj_company_code"];
        [lastCacheIndexDic setObject:proj_company_code forKey:@"proj_company_code"];
        
        NSInteger proj_import_time = [res intForColumn:@"proj_import_time"];
        [lastCacheIndexDic setObject:[NSNumber numberWithInteger:proj_import_time] forKey:@"proj_import_time"];
        
        NSString *proj_station_type = [res stringForColumn:@"proj_station_type"];
        [lastCacheIndexDic setObject:proj_station_type forKey:@"proj_station_type"];
        
        NSString *proj_company = [res stringForColumn:@"proj_company"];
        [lastCacheIndexDic setObject:proj_company forKey:@"proj_company"];
        
        NSString *proj_bu_code =  [res stringForColumn:@"proj_bu_code"];
        [lastCacheIndexDic setObject:proj_bu_code forKey:@"proj_bu_code"];
        
        NSString *proj_code =  [res stringForColumn:@"proj_code"];
        [lastCacheIndexDic setObject:proj_code forKey:@"proj_code"];
        
        NSString *proj_lat = [res stringForColumn:@"proj_lat"];
        [lastCacheIndexDic setObject:proj_lat forKey:@"proj_lat"];
        
        NSString *proj_establish_time =  [res stringForColumn:@"proj_establish_time"];
        [lastCacheIndexDic setObject:proj_establish_time forKey:@"proj_establish_time"];
        
        NSString *proj_name =  [res stringForColumn:@"proj_name"];
        [lastCacheIndexDic setObject:proj_name forKey:@"proj_name"];
        
        NSInteger proj_link_max_distan =  [res intForColumn:@"proj_link_max_distan"];
        [lastCacheIndexDic setObject:[NSNumber numberWithInteger:proj_link_max_distan] forKey:@"proj_link_max_distan"];
        
        NSString *proj_tower_type = [res stringForColumn:@"proj_tower_type"];
        [lastCacheIndexDic setObject:proj_tower_type forKey:@"proj_tower_type"];
        
        NSInteger proj_submit_time =  [res intForColumn:@"proj_submit_time"];
        [lastCacheIndexDic setObject:[NSNumber numberWithInteger:proj_submit_time] forKey:@"proj_submit_time"];
        
        NSString *proj_module_name_ls =  [res stringForColumn:@"proj_module_name_ls"];
        [lastCacheIndexDic setObject:proj_module_name_ls forKey:@"proj_module_name_ls"];
        
        NSInteger proj_status =  [res intForColumn:@"proj_status"];
        [lastCacheIndexDic setObject:[NSNumber numberWithInteger:proj_status] forKey:@"proj_status"];
        
        NSString *proj_tower_height = [res stringForColumn:@"proj_tower_height"];
        [lastCacheIndexDic setObject:proj_tower_height forKey:@"proj_tower_height"];
        
        NSInteger proj_link_id_ls =  [res intForColumn:@"proj_link_id_ls"];
        [lastCacheIndexDic setObject:[NSNumber numberWithInteger:proj_link_id_ls] forKey:@"proj_link_id_ls"];
        
        NSString *proj_bu_name = [res stringForColumn:@"proj_bu_name"];
        [lastCacheIndexDic setObject:proj_bu_name forKey:@"proj_bu_name"];
        
        [proj_codeArr addObject:proj_code];
        [lastCacheArr addObject:lastCacheIndexDic];
        [picTimeArr addObject:[NSNumber numberWithInteger: proj_submit_time]];//优化:可以根据提交时间排序,做法:在详情界面,更新下外面的大表格的提交时间
        
    }
     NSLog(@"getCacheArr2数据库取出共----%ld条数据",proj_codeArr.count);
    
    
    //拍照时间排序
    NSArray *numberResult = [picTimeArr sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        return [obj2 compare:obj1];//时间最大的靠前,显示最新会议
    }];
    
    NSMutableArray *tmpCacheArr =[[NSMutableArray alloc] init];//临时接收
    for (int i = 0; i0) {
        _dataArr= lastCacheArr;
        _searchDataArr = lastCacheArr;
    }
    [_db close];
}

有新数据时你可以根据某些条件去更新数据库,如下

//刷新看到重复数据,就更新数据库
- (void)updateCacheArr:(NSMutableArray *)cacheArr{//什么是调用更新方法.
    
    // 路径
    NSString *documentsPath =  [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    
    _db = [FMDatabase databaseWithPath: [documentsPath stringByAppendingPathComponent:@"projectList.sqlite"]];
    [_db open];
  
    
   
    for (int i =0; i%@",proj_code);
    }
    [_db close];
}


拍照给相机显示水印

正在拍摄的界面
拍摄完预览的图片

实现原理 使用第三方的相机框架(ZHGWaterMarkMeetingCameraVC.h).可以自定义水印.

极光推送

场景:
1.上传操作服务器推送到手机
2.后台推送到手机

加载html本地显示

iOS现场系统app使用的技术点总结_第5张图片
提交审核下面是html网页

实现原理:
1.下载html.zip到本地
2.解压
3.根据本地路径去取响应子文件的html文件
4.webview去加载
代码:

#pragma mark ---getWebHtmlData
- (void)getWebHtmlData{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // 取得沙盒目录
    NSString * chchePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
    // 要检查的文件目录
    NSString *filePath1 = [chchePath  stringByAppendingPathComponent:@"link_describe"];
    
    
    //优化:可以删除压缩包link_describe.zip
    NSString * path2 = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
    // 要检查的文件目录
    NSString *zipFilePath = [path2  stringByAppendingPathComponent:@"link_describe.zip"];
    
    if ([fileManager fileExistsAtPath:zipFilePath]) {
        [fileManager removeItemAtPath:zipFilePath error:nil];
        NSLog(@"删除了link_describe.zip");
    }

    NSMutableDictionary *dictWebContent = [[NSMutableDictionary alloc]init];
        [NetWorkRequest reductMoneyMsg:dictWebContent complete:^(id json) {
            if ([json[@"error"] integerValue] == 0) {
                _webDataArr =json[@"result"];
                webUrl =json[@"result"][@"describe_url"];//"http://gdworksite.file.alimmdn.com/link_describe/link_describe.zip";
                //没html和更新html时都要重新下载
                if (![json[@"result"][@"describe_md5"]isEqualToString: [GlobalInfo instance].htmlMD5]  || ![fileManager fileExistsAtPath:filePath1]) {//重新下载
//                    NSLog(@"htmlMD5--%@",[GlobalInfo instance].htmlMD5);
//                    NSLog(@"describe_md5----%@",json[@"result"][@"describe_md5"]);
                    //根据文件名删除文件
                    NSString * path1 = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches/link_describe"];
                    //就删除原沙盒文件
                    [fileManager removeItemAtPath:path1 error:nil];
                    
                    //更新md5并保存
                     [GlobalInfo instance].htmlMD5 =json[@"result"][@"describe_md5"];
                    //下载资源
                    /* 创建网络下载对象 */
                    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
                    
                    /* 下载地址 */
                    // 1.创建网路路径
                    NSURL* url = [NSURL URLWithString:webUrl];
                    NSURLRequest *request = [NSURLRequest requestWithURL:url];
                    
                    /* 下载路径 */
                    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
                    NSLog(@"path-----%@",path);
                    
                    NSLog(@"url.lastPathComponent-----%@",url.lastPathComponent);//link_describe.zip
                    NSString *filePath = [path stringByAppendingPathComponent:url.lastPathComponent];
                    
                    /* 开始请求下载 */
                    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
                        
                        NSLog(@"下载进度:%.0f%", downloadProgress.fractionCompleted * 100);
                        
                    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
                        
                        /* 设定下载到的位置 */
    //                    NSLog(@"response----%@",response);
                        return [NSURL fileURLWithPath:filePath];
                        
                    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
                        NSLog(@"filePath----%@",filePath);
                        NSLog(@"下载完成");
                        //解压
                        NSString *imgFilePath = [filePath path];// 将NSURL转成NSString
                        NSLog(@"FromFilePath = %@",imgFilePath);
                        // imgFilePath = /var/mobile/Containers/Data/Application/6037CE56-2DB0-4984-94A9-00DB89B122E6/Library/Caches/link_describe.zip
                        NSArray *documentArray =  NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
                        //            NSString *path = [[documentArray lastObject] stringByAppendingPathComponent:@"Caches"];
                        NSString *path = [documentArray lastObject];
                        NSLog(@"Topath----%@",path);
                        //path----/var/mobile/Containers/Data/Application/6037CE56-2DB0-4984-94A9-00DB89B122E6/Library/Caches
                        //从imgFilePath解压到path
                        //解压到当前文件夹
                        [self releaseZipFilesWithUnzipFileAtPath:imgFilePath Destination:path];
                        //优化:上面解压成功这里可以删除压缩文件.
                        
                        
                    }];/* 开始请求下载结束 */
                    [downloadTask resume];
                }//重新下载结束
                    [[NSUserDefaults standardUserDefaults] synchronize];
                }//请求成功结束
             } error:^{
        
        }];//NetWorkRequest网络结束
}



// 解压
- (void)releaseZipFilesWithUnzipFileAtPath:(NSString *)zipPath Destination:(NSString *)unzipPath{
    NSError *error;
    if ([SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath overwrite:YES password:nil error:&error delegate:self]) {
        NSLog(@"success");
        NSLog(@"unzipPath = %@",unzipPath);
        
        //-----Documents
        NSString *docsDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches/link_describe"];
        NSLog(@"docsDir---%@",docsDir);
        //docsDir---/var/mobile/Containers/Data/Application/C171EA6F-FFD5-4811-BE7A-7D91694B1248/Library/Caches/link_describe
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:docsDir];
        //打印dirEnum
        //        NSLog(@"dirEnum---%@",dirEnum);
        NSString *fileName;
        //        NSInteger num = fileName.integerValue;//没用的,取不到,因为是个文件.没有哪个方法/
        //只想遍历第一层文件
        //nextObject什么意思
        while (fileName = [dirEnum nextObject]) {
            
            NSLog(@"FielName>>>>>> : %@" , fileName);
            
            NSLog(@"FileFullPath>>>>>>>>>>>>>>> : %@" , [docsDir stringByAppendingPathComponent:fileName]) ;
//            NSString * url = [docsDir stringByAppendingPathComponent:fileName];
            
            
            
            
        }
        
    }else {
        NSLog(@"解压失败---%@",error);
    }
    //没用了
//    NSLog(@"htmlDic---%@",htmlDic);
}

上传照片到阿里百川

总结: 阿里百川不好用,异步操作和循环时会把错误的url也返回给我,很多bug没人修复,客服联系不上,不建议使用.

代码封装:

//上传图片到阿里百川
+(void)upLloadImageDate:(UIImage *)image  name:(NSString *)name file:(NSString *)fileName iamgeBlock:(complete)block error:(errorComplete)errorfinish{
    
    [[ALBBMedia sharedInstance] setTaeFileEngine: [ALBBMediaServiceFactory getService:[DEMOTokenGenerator new]]];
    if (!DEMO_ENGINE) {
        NSLog(@"tae sdk 未初始化");
    }
    
        NSData *data=UIImageJPEGRepresentation(image, 1.0f);

    
    TFEUploadNotification *notification = [TFEUploadNotification
                                           notificationWithProgress:^(TFEUploadSession *session, NSUInteger progress) {
                                               NSLog(@"%lu", (unsigned long) progress);

                                               
                                           }
                                           success:^(TFEUploadSession *session, NSString *url) {
                                               NSLog(@"图片上传成功%@", session);
                                               if (block) {
                                                   block(url);
                                               }

                                           }
                                           failed:^(TFEUploadSession *session, NSError *error) {
                            
                                               NSLog(@"error happend.%@", error);
                                               if (errorfinish) {
                                                   errorfinish();
                                               }
                                           }
                                           ];

   demoUpload(DEMO_TYPE_DATA, data, notification);//不能注释

你可能感兴趣的:(iOS现场系统app使用的技术点总结)