1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/chenzm_186-RequestAndLogManager

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Вот перевод текста на русский язык:

[self.timeFormatter stringFromDate:[LogManager getCurrDate]]; NSString* writeStr = [NSString stringWithFormat:@"[%@]-[%@]-%@\n",timeStr,module,parmaStr];

// 写入 данных [self writeFile:filePath stringData:writeStr];

NSLog(@"Запись в журнал:%@",filePath); }); }

/** Чтение файла @param fileName Путь к файлу */

  • (NSString *)readFile:(NSString *)fileName{ NSString *filePath = [self getLogPathWithDate:fileName]; NSData *data = [NSData dataWithContentsOfFile:filePath]; NSString *logStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; return logStr; }

/** Получение имени файла по дате @param dateStr Дата в формате yyyy-MM-dd @return Возвращает путь к файлу */ -(NSString )getLogPathWithDate:(NSString )dateStr{ NSString fileName = nil; if(dateStr||dateStr > 0){ fileName = dateStr; }else{ fileName = [self.dateFormatter stringFromDate:[NSDate date]]; } NSString filePath = [NSString stringWithFormat:@"%@%@",self.basePath,fileName]; return filePath; }

///Очистка устаревших журналов

  • (void)clearExpiredLog{

    // Получение всех файлов из каталога журнала NSArray* files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.basePath error:nil]; for (NSString* file in files) {

      NSDate* date = [self.dateFormatter dateFromString:file];
      if (date) {
          NSTimeInterval oldTime = [date timeIntervalSince1970];
          NSTimeInterval currTime = [[LogManager getCurrDate] timeIntervalSince1970];
    
          NSTimeInterval second = currTime - oldTime;
          int day = (int)second / (24 * 3600);
          if (day >= LogMaxSaveDay) {
              // Удаление файла
              [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@",self.basePath,file] error:nil];
              NSLog(@"[%@] Файл журнала был удалён!",file);
          }
      }

    }

}

///Проверка необходимости загрузки журнала

  • (void)checkLogNeedUpload{ // Отправка запроса для получения информации о необходимости загрузки журнала с сервера [kZMEngine checkUploadLogWithResponse:^(id response) { if ([kZMEngine getResultCode:response] == 1) { NSDictionary *dic = [kZMEngine getResultData:response]; if (dic&&[dic isKindOfClass:[NSDictionary class]]&&dic.allKeys>0) { [self uploadLog:dic]; }else{ NSLog(@"Ошибка запроса, данные не получены!"); } }else{ NSLog(@"Ошибка проверки журнала!"); } }; }

#pragma mark - Private

/** Обработка необходимости загрузки журнала @param resultDic Словарь, содержащий информацию о дате */

  • (void)uploadLog:(NSDictionary*)resultDic{

    if (!resultDic) { return; }

    // 0 не загружать, 1 загрузить за N дней, 2 загрузить все int type = [resultDic[@"type"] intValue]; // Успешное создание сжатого файла BOOL created = NO; if (type == 1) { // Загрузить за указанный период времени

      // "dates": ["2017-03-01", "2017-03-11"]
      NSArray* dates = resultDic[@"dates"];
    
      // Сжать журнал
      created = [self compressLog:dates];

    }else if(type == 2){ // Загрузить всё

      // Сжать журнал
      created = [self compressLog:nil];

    }

    if (created) { // Загрузка [self uploadLogToServer:^(BOOL boolValue) { if (boolValue) { NSLog(@"Загрузка журнала успешно---->>",nil); // Удалить сжатый файл журнала [self deleteZipFile]; }else{ NSLog(@"Ошибка загрузки журнала!!",nil); } }; } }

/** Сжатие журнала @param dates Диапазон дат, пустой означает все @return Результат выполнения */

  • (BOOL)compressLog:(NSArray*)dates{

    // Сначала очистить журналы за несколько дней [self clearExpiredLog];

    // Получить все файлы из каталога журнала NSArray* files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.basePath error:nil]; // Путь к сжатому файлу NSString * zipFile = [self.basePath stringByAppendingString:ZipFileName] ;

    ZipArchive* zip = [[ZipArchive alloc] init]; // Создать zip-архив BOOL created = [zip CreateZipFile2:zipFile]; if (!created) { // Закрыть файл [zip CloseZipFile2]; return NO; }

    if (dates) { // Загрузить за указанный диапазон дат for (NSString* fileName in files) { if ([dates containsObject:fileName]) { // Файлы, которые будут сжаты

... Данный фрагмент написан на языке Objective-C.

Ниже представлен перевод этого фрагмента на русский язык:

NSString *file = [self.basePath stringByAppendingString:fileName];
// 判断文件是否存在
if ([[NSFileManager defaultManager] fileExistsAtPath:file]) {
    // 将日志添加到zip包中
    [zip addFileToZip:file newname:fileName];
}
}

} else {
    // 全部
    for (NSString* fileName in files) {
        // 将要被压缩的文件
        NSString *file = [self.basePath stringByAppendingString:fileName];
        // 判断文件是否存在
        if ([[NSFileManager defaultManager] fileExistsAtPath:file]) {
            // 将日志添加到zip包中
            [zip addFileToZip:file newname:fileName];
        }
    }
}

// 关闭文件
[zip CloseZipFile2];
return YES;
}

/**
 *  上传日志到服务器
 *
 *  @param returnBlock 成功回调
 */
- (void)uploadLogToServer:(void(^)(BOOL boolValue))returnBlock{
    NSString *filePath = [self getLogPathWithDate:@""];
    [kZMEngine updateFileWithfileName:ZipFileName filePath:filePath response:^(id response) {
        if ([kZMEngine getResultCode:response] == 1) {
            returnBlock(YES);
        }else{
            returnBlock(NO);
        }
    }];
}

/**
 *  删除日志压缩文件
 */
- (void)deleteZipFile{

    NSString* zipFilePath = [self.basePath stringByAppendingString:ZipFileName];
    if ([[NSFileManager defaultManager] fileExistsAtPath:zipFilePath]) {
        [[NSFileManager defaultManager] removeItemAtPath:zipFilePath error:nil];
    }
}

/**
 *  写入字符串到指定文件,默认追加内容
 *
 *  @param filePath   文件路径
 *  @param stringData 待写入的字符串
 */
- (void)writeFile:(NSString*)filePath stringData:(NSString*)stringData{

    // 待写入的数据
    NSData* writeData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
    // NSFileManager 用于处理文件
    BOOL createPathOk = YES;
    if (![[NSFileManager defaultManager] fileExistsAtPath:[filePath stringByDeletingLastPathComponent] isDirectory:&createPathOk]) {
        // 目录不存先创建
        [[NSFileManager defaultManager] createDirectoryAtPath:[filePath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
    }
    if(![[NSFileManager defaultManager] fileExistsAtPath:filePath]){
        // 文件不存在,直接创建文件并写入
        [writeData writeToFile:filePath atomically:NO];
    }else{

        // NSFileHandle 用于处理文件内容
        // 读取文件到上下文,并且是更新模式
        NSFileHandle* fileHandler = [NSFileHandle fileHandleForUpdatingAtPath:filePath];

        // 跳到文件末尾
        [fileHandler seekToEndOfFile];

        // 追加数据
        [fileHandler writeData:writeData];

        // 关阀文件
        [fileHandler closeFile];
    }
}
@end
``` **Перевод кода на русский язык:**

titleLbl = [UILabel new]; titleLbl.frame = CGRectMake(10, 20, [UIScreen mainScreen].bounds.size.width - 20, 20); titleLbl.textAlignment = NSTextAlignmentCenter; titleLbl.textColor = [UIColor purpleColor]; if (@available(iOS 8.2, *)) { titleLbl.font = [UIFont systemFontOfSize:18 weight:1]; } else { titleLbl.font = [UIFont systemFontOfSize:18]; } titleLbl.text = @"打印日志"; [self addSubview:titleLbl]; return titleLbl;


-(UITextView *)textView{
    if (!_textView) {
        _textView = [UITextView new];
        _textView.font = [UIFont systemFontOfSize:14];
        _textView.textColor = [UIColor darkGrayColor];
        CGRect frame = CGRectMake(10, CGRectGetMaxY(self.titleLbl.frame),[UIScreen mainScreen].bounds.size.width - 20,[UIScreen mainScreen].bounds.size.height - 50);
        _textView.frame = frame;
        _textView.showsHorizontalScrollIndicator = NO;
        [_textView setEditable:NO];
        [self addSubview:_textView];
    }
    return _textView;
}


-(void)dealloc{
    
}
@end

Применение экземпляра приложения «打印日志», в котором ещё не внедрён интерфейс для загрузки запросов:

В файле LogManager.m можно временно закомментировать интерфейс загрузки запросов, чтобы избежать ошибок:

#import "LogManager.h"
#import "ZMLogView.h"

/// Отображение журнала
@property(nonatomic,strong) ZMLogView *logView;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self testForLocalLog];
}

/// Запись данных в локальный файл и отображение
-(void)testForLocalLog{
    // Запись данных в локальный файл
    LLog(@"Ошибка",@"Пять оу грубый");
    // Получение информации журнала и отображение
    NSString *str = [[LogManager sharedInstance] readFile:@"2018-09-11"];
    NSLog(@"%@",str);
    // Рендеринг
    [self.logView logInfo:str];
}

#pragma mark - lazyload

-(ZMLogView *)logView{
    if (!_logView) {
        _logView = [ZMLogView initLogView];
        [self.view addSubview:_logView];
    }
    return _logView;
}

Использование AFNetworking для интеграции интерфейса

1. Запрос GET

/**
 Запрос GET
 @param url Ссылка
 @param params Параметры
 @param success Блок успеха
 @param failure Блок неудачи
 */
- (void)base_GetWithUrl:(NSString *)url parameters:(NSDictionary *)params success:(void(^)(id success))success failure:(void(^)(id failure))failure{
    
    url = [NSString stringWithFormat:@"%@%@",kURLMain,url];
    
    // Создание объекта запроса
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];  // Установка данных запроса
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];// Установка данных ответа
    // Настройка заголовка запроса
    [ZMBaseEngine setHttpHeaderWithManager:manager];
    // Установка времени ожидания
    manager.requestSerializer.timeoutInterval = 10.0f;
    //NSString *strUrl = [NSString stringWithFormat:@"%@%@",kURLMain,url];
    
    [manager GET:url parameters:params progress:^(NSProgress * _Nonnull downloadProgress) {

    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // Анализ JSON
        NSDictionary *dic = [self jsonToDic:responseObject];
        success(dic);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self  handlingError:error failure:failure];
    }];
}

2. Запрос POST

/**
 Запрос POST
 @param url Ссылка
 @param params Параметры
 @param success Блок успеха
 @param failure Блок неудачи
 */
- (void)base_PostWithUrl:(NSString *)url parameters:(id)params success:(void(^)(id success))success failure:(void(^)(id failure))failure{
    
    url = [NSString stringWithFormat:@"%@%@",kURLMain,url];
    
    // Создание объекта запроса
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];  // Установка данных запроса
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];// Установка данных ответа
    // Настройка заголовка запроса
    [ZMBaseEngine setHttpHeaderWithManager:manager];
    // Установка времени ожидания
    manager.requestSerializer.timeoutInterval = 10.0f;
    [manager POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
    
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // Анализ JSON
        NSDictionary *dic = [self jsonToDic:responseObject];
        success(dic);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull
``` ### 3. Изображение загружается

```oc
/**
 Изображение загружается
 
 @param imgData Данные изображения
 @param fileName Имя изображения
 @param type Тип
 @param url Ссылка
 @param params Параметры
 @param progress Код прогресса
 @param success Успешный код
 @param failure Код ошибки
 */
- (void)base_UpLoadImage:(NSData *)imgData fileName:(NSString *)fileName imgType:(NSString *)type PostWithURL:(NSString *)url parameters:(id)params progress:(void(^)(id progress))progress success:(void(^)(id success))success failure:(void(^)(id failure))failure{
    
    url = [NSString stringWithFormat:@"%@%@",kURLMain,url];
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    // Устанавливаем время ожидания
    manager.requestSerializer.timeoutInterval = 30.0f;
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    
    manager.responseSerializer =[AFHTTPResponseSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html",@"image/png",@"image/jpeg",nil];
    [manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        // Загружаем данные, имя домена — fileName
        [formData appendPartWithFileData:imgData name:@"imageFile"fileName:fileName mimeType:[NSString stringWithFormat:@"image/%@",type]];
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        progress(uploadProgress);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // Анализируем JSON
        NSDictionary *dic = [self jsonToDic:responseObject];
        success(dic);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self handlingError:error failure:failure];
    }];
}

4. Файл загружается

/**
 Файл загружается
 
 @param url Ссылка
 @param params Параметры
 @param fileName Имя файла
 @param upName Имя для загрузки
 @param filePath Путь
 @param progress Прогресс кода
 @param success Код успеха
 @param failure Ошибка
 */
- (void)base_UpdateFileWithUrl:(NSString*)url parameters:(NSMutableDictionary*)params fileName:(NSString*)fileName upName:(NSString *)upName filePath:(NSString *)filePath progress:(void(^)(id progress))progress success:(void(^)(id success))success failure:(void(^)(id failure))failure{
    
    url = [NSString stringWithFormat:@"%@%@",kURLMain,url];
    if (!upName) {
        upName = fileName;
    }
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // Запрос заголовка установлен
    [ZMBaseEngine setHttpHeaderWithManager:manager];
    [manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        /*
         Первый параметр: URL-адрес файла
         Второй параметр: имя параметра file
         Третий параметр: имя на сервере
         Четвёртый параметр: тип файла
         */
        if (filePath&&fileName) {
            NSData*fileData = [NSData dataWithContentsOfFile:filePath];
            //        [formData appendPartWithFileURL:[NSURL fileURLWithPath:@""] name:fileName error:nil];
            [formData appendPartWithFileData:fileData name:upName fileName:fileName mimeType:@"application/zip"];
        }
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        progress(uploadProgress);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // Анализ JSON
        NSDictionary *dic = [self jsonToDic:responseObject];
        success(dic);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self handlingError:error failure:failure];
    }}];
}

5. Заголовок запроса / обработка ошибок и т. д.

/// Интерфейс запроса заголовка
+(void)setHttpHeaderWithManager:(AFHTTPSessionManager *)manager{
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
#pragma mark --- 请求头的设置自Header
    // Информация о приложении
    NSDictionary *dicInfo = [[NSBundle mainBundle] infoDictionary];
    // Версия приложения
    NSString *strAppVersion = [dicInfo objectForKey:@"CFBundleShortVersionString"];
    // Название системы
    NSString *strSysName =[[UIDevice currentDevice]systemName];
    // Системная версия
    NSString *strSysVersion = [[UIDevice
``` ### currentDevice]systemVersion];
    // Оборудование
    NSString *strModel = [[UIDevice currentDevice] model];
    // Локализованное название модели оборудования
    NSString *strLocModel = [[UIDevice currentDevice] localizedModel];

    // Платформа оборудования
    [manager.requestSerializer setValue:strSysName forHTTPHeaderField:@"platform"];
    // Тип оборудования (модель, локализованное название)
    [manager.requestSerializer setValue:[NSString stringWithFormat:@"model:%@\t locModel:%@", strModel, strLocModel] forHTTPHeaderField:@"type"];
    // Версия системы
    [manager.requestSerializer setValue:strSysVersion forHTTPHeaderField:@"sysVersion"];
    // Версия приложения
    [manager.requestSerializer setValue:strAppVersion forHTTPHeaderField:@"appVersion"];

    // ---------  other test   -----------
    [manager.requestSerializer setValue:@"19644" forHTTPHeaderField:@"MEMBERID"];
    [manager.requestSerializer setValue:@"1" forHTTPHeaderField:@"X-MUYAN-MECHINE"];
    [manager.requestSerializer setValue:@"xx" forHTTPHeaderField:@"X-MUYAN-SIGN"];
    [manager.requestSerializer setValue:@"43" forHTTPHeaderField:@"X-MUYAN-VERSION"];
}

#pragma mark - other methods
/// Интерфейс запроса ошибки обработки
-(void)handlingError:(NSError * _Nonnull)error failure:(void(^)(id failure))failure{
    // Получение информации об ошибке
    NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
#if DEBUG
    NSLog(@"%@", error.userInfo);
#else
#endif
    NSString *strError = @"Нет подключения к сети: проверьте!";
    NSString *errDesStr = error.userInfo[@"NSLocalizedDescription"];
    NSArray *arr = [errDesStr componentsSeparatedByString:@" "];
    NSString *lastStr = arr.lastObject;
    NSString *errCodeStr;
    if ([self engineValidateStr:lastStr belongToStr:@"()1234567890."]) {
        errCodeStr = [lastStr substringWithRange:NSMakeRange(1, lastStr.length - 2)]?:@"";
    } else {
        errCodeStr = lastStr;
    }

    // Печать информации об ошибке
    NSString *dataStr = nil;
    if (data.length > 0) {
        dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    } else {
        dataStr = @"Журнал ошибок пуст";
    }
    NSString *errorResponse = error.userInfo[@"com.alamofire.serialization.response.error.response"];
    NSString *errorUrl = error.userInfo[@"NSErrorFailingURLKey"];
    NSString *errorStr = [NSString stringWithFormat:@"... начало ...<br><br>NSErrorFailingURLKey:<br>%@<br><br>NSLocalizedDescription:<br>%@<br><br>com.alamofire.serialization.response.error.response:<br>%@<br><br>com.alamofire.serialization.response.error.data:<br>%@<br><br>... конец ...", errorUrl, errDesStr, errorResponse, dataStr];
        data = [errorStr dataUsingEncoding:NSUTF8StringEncoding];
    [self openHtmlError:data target:[self engineGetCurrentVC]];

    NSDictionary *dic = @{Req_resultCode:errCodeStr, Req_errorMessage:strError, Req_errorData:data?:@""};
    // Обратный вызов блока кода ошибки
    failure(dic);
}

- (NSDictionary *)jsonToDic:(NSData *)jsonData{
    NSError *error = nil;
    NSData *data = jsonData;
    NSDictionary *dicData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

    if (error) {
        return @{};
    } else {
        return dicData;
    }}

/**
Проверка принадлежности символа заданной строке
@param str Символ
@param toStr Строка
*/
- (BOOL)engineValidateStr:(NSString*)str belongToStr:(NSString *)toStr{
    BOOL res = YES;
    NSCharacterSet* tmpSet = [NSCharacterSet characterSetWithCharactersInString:toStr];
    int i = 0;
    while (i < str.length) {
        NSString *string = [str substringWithRange:NSMakeRange(i, 1)];
        NSRange range = [string rangeOfCharacterFromSet:tmpSet];
        if (range.length == 0) {
            res = NO;
            break;
        }
        i++;
    }
    return res;
}

///Печать информации об ошибке
-(void)openHtmlError:(NSData *)data target:(UIViewController *)target{
    //#ifdef Debug
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if (str&&str.length>0) {
        ZMWKWebViewVC *vc = [ZMWKWebViewVC new];
        [vc.wkWebView loadHTMLString:str baseURL:[NSURL URLWithString:@"www://baidu.com"]];
        [target presentViewController:vc animated:YES completion:nil];
    }else{
        
    }
    //#else **Получение текущего viewcontroller экрана**
  • (UIViewController *)engineGetCurrentVC{ // 定义一个变量存放当前屏幕显示的 view controller UIViewController *result = nil;

    // Получаем текущее активное окно приложения UIWindow * window = [[UIApplication sharedApplication] keyWindow];

    // windowLevel — это позиция окна в направлении Z-оси, по умолчанию значение UIWindowLevelNormal if (window.windowLevel != UIWindowLevelNormal) { // Получаем все окна приложения NSArray *windows = [[UIApplication sharedApplication] windows]; for(UIWindow * tmpWin in windows) { // Находим окно по умолчанию (активное окно) if (tmpWin.windowLevel == UIWindowLevelNormal) { // Присваиваем окну значение окна по умолчанию window = tmpWin; break; } } }

    // Получаем текущий отображаемый вид окна UIView *frontView = [[window subviews] objectAtIndex:0];

    // Получаем следующий респондент вида, который возвращает UIViewController или его родительский вид id nextResponder = [frontView nextResponder];

    // Проверяем, является ли следующий респондент видом UIViewController if ([nextResponder isKindOfClass:[UIViewController class]]) { result = nextResponder; } else { result = window.rootViewController; } return result; }


**Ошибка h5 интеграции: вызов метода класса при ошибке запроса интерфейса**

```oc
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
@interface ZMWKWebViewVC : UIViewController
@property (nonatomic, strong) WKWebView *wkWebView;
-(void)zm_WKLoadUrl:(NSString *)url;

@end
@interface ZMWKWebViewVC ()<WKUIDelegate,WKNavigationDelegate>


@property (nonatomic, strong) UIProgressView *progressView;


///错误标题
@property(nonatomic,strong)UILabel *titleLbl;

///退出按钮
@property(nonatomic,strong)UIButton *dismissBtn;


@end

@implementation ZMWKWebViewVC

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    //进度条初始化
    self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 20, [[UIScreen mainScreen] bounds].size.width, 2)];
    _progressView.backgroundColor = [UIColor blueColor];
    //设置进度条的高度,下面这句代码表示进стуика в 1 раз, высота в 1.5 раза.
    _progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f);
    [self.view addSubview:_progressView];
    [self dismissBtn];
}

-(void)zm_WKLoadUrl:(NSString *)url{
    [self.wkWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"estimatedProgress"]) {
        _progressView.progress = self.wkWebView.estimatedProgress;
        if (_progressView.progress == 1) {
            /*
             *Добавление простого анимационного эффекта, изменение высоты progressView до 1,4 раза, и восстановление до 1,5 раза после начала загрузки страницы через прокси.
             *Длительность анимации составляет 0,25 секунды, задержка перед началом анимации - 0,3 секунды.
             *После завершения анимации progressView скрывается.
             */
            [UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
                _progressView.transform = CGAffineTransformMakeScale(1.0f, 1.4f);
            } completion:^(BOOL finished) {
                _progressView.hidden = YES;

            }];
        }
    }else{
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}


//Начало загрузки
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    //Отображение progressView при начале загрузки страницы
    _progressView.hidden = NO;
    //Восстановление высоты progressView до 1,5 раза при начале загрузки страницы
    _progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f);
    //Предотвращение перекрытия progressView страницей
    [self.view bringSubviewToFront:_progressView];
}

//Загрузка завершена
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    //Скрытие progressView после завершения загрузки
    _progressView.hidden = YES;
}

//Ошибка загрузки
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    //Скрытие progressView при ошибке загрузки
    //_progressView.hidden = YES;
}
``` **decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{**
    NSLog(@"%@",webView.URL.absoluteString);
    
    decisionHandler(WKNavigationActionPolicyAllow);
}

- (void)dealloc {
    [self.wkWebView removeObserver:self forKeyPath:@"estimatedProgress"];
}

//设备宽高
#define kWebIphone_W [UIScreen mainScreen].bounds.size.width
#define kWebIphone_H [UIScreen mainScreen].bounds.size.height

#pragma mark - lazyload

- (WKWebView *)wkWebView{
    if (_wkWebView == nil){
        //创建网页配置对象
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
        // 创建设置对象
        WKPreferences *preference = [[WKPreferences alloc]init];
        // 设置字体大小(最小的字体大小)
        preference.minimumFontSize = 40;
        // 设置偏好设置对象
        config.preferences = preference;
        // 创建WKWebView
        _wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0,CGRectGetMaxY(self.titleLbl.frame), kWebIphone_W, kWebIphone_H - CGRectGetMaxY(self.titleLbl.frame) - 10) configuration:config];
        _wkWebView.scrollView.bounces = NO;
        _wkWebView.UIDelegate = self;
        _wkWebView.navigationDelegate = self;
        [self.view addSubview:_wkWebView];
        [self.wkWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
    }
    return  _wkWebView;
}

-(UILabel *)titleLbl{
    if (!_titleLbl) {
        _titleLbl = [UILabel new];
        _titleLbl.frame = CGRectMake(0, 20, kWebIphone_W, 30);
        _titleLbl.textColor = [UIColor purpleColor];
        _titleLbl.textAlignment = NSTextAlignmentCenter;
        _titleLbl.text = @"错误信息";
        if (@available(iOS 8.2, *)) {
            _titleLbl.font = [UIFont systemFontOfSize:18 weight:1.0];
        } else {
            _titleLbl.font = [UIFont systemFontOfSize:18];
        }
        [self.view addSubview:_titleLbl];
        
        UILabel *lineLbl = [UILabel new];
        lineLbl.frame = CGRectMake(_titleLbl.bounds.origin.x,CGRectGetMaxY(_titleLbl.bounds) - 0.5, _titleLbl.bounds.size.width, 0.5);
        lineLbl.backgroundColor = [UIColor lightGrayColor];
        [_titleLbl addSubview:lineLbl];
    }
    return _titleLbl;
}

-(UIButton *)dismissBtn{
    if (!_dismissBtn) {
        _dismissBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _dismissBtn.frame = CGRectMake(10, CGRectGetMinY(self.titleLbl.frame), 50, 20);
        
        _dismissBtn.layer.masksToBounds = YES;
        _dismissBtn.layer.cornerRadius = 5;
        _dismissBtn.titleLabel.font = [UIFont systemFontOfSize:14];
        [_dismissBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
        [_dismissBtn setTitle:@"返回" forState:UIControlStateNormal];
        [_dismissBtn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];

        [self.view addSubview:_dismissBtn];
    }
    return _dismissBtn;
}

-(void)btnAction:(UIButton *)sender{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

1. Интеграция POST и get запросов на основе AFNetworking. 2. Обработка журналов ошибок запросов, подходит для использования в проектах. 3. Запись информации в локальный журнал и упаковка сжатых файлов для загрузки, подходит для отслеживания онлайн-версий и привычек пользователей. Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/chenzm_186-RequestAndLogManager.git
git@api.gitlife.ru:oschina-mirror/chenzm_186-RequestAndLogManager.git
oschina-mirror
chenzm_186-RequestAndLogManager
chenzm_186-RequestAndLogManager
master