Слияние кода завершено, страница обновится автоматически
pod 'BAWKWebView'
pod search BAWKWebView
не находит последнюю версию, выполните команду pod setup
для обновления локального кэша spec (может занять несколько минут), а затем выполните поиск снова. pod setup
: инициализацияpod repo update
: обновление репозиторияpod search BAWKWebView
#import "BAKit_WebView.h"
#import <WebKit/WebKit.h>
NS_ASSUME_NONNULL_BEGIN
#define kBAKit_WK_title @"title"
#define kBAKit_WK_estimatedProgress @"estimatedProgress"
#define kBAKit_WK_URL @"URL"
#define kBAKit_WK_contentSize @"contentSize"
/**
Вызывается при начале загрузки
@param webView webView
@param navigation navigation
*/
typedef void (^BAKit_webView_didStartProvisionalNavigationBlock)(WKWebView * _Nullable webView, WKNavigation *navigation);
/**
Вызывается, когда начинается возврат содержимого
@param webView webView
@param navigation navigation
*/
typedef void (^BAKit_webView_didCommitNavigationBlock)(WKWebView *webView, WKNavigation *navigation);
``````markdown
/**
Вызывается после завершения загрузки страницы
@param webView webView
@param navigation navigation
*/
typedef void (^BAKit_webView_didFinishNavigationBlock)(WKWebView *webView, WKNavigation *navigation);
/**
Вызывается при неудачной загрузке страницы
@param webView webView
@param navigation navigation
*/
typedef void (^BAKit_webView_didFailProvisionalNavigationBlock)(WKWebView *webView, WKNavigation *navigation);
/**
Получает текущий прогресс загрузки webview, чтобы определить, загружается ли что-то
@param isLoading Загружается ли что-то
@param progress Прогресс загрузки web, диапазон: 0.0f ~ 1.0f
*/
typedef void (^BAKit_webView_isLoadingBlock)(BOOL isLoading, CGFloat progress);
/**
Получает текущий заголовок webview
@param title Заголовок
*/
typedef void (^BAKit_webView_getTitleBlock)(NSString *title);
/**
Метод, вызываемый webview при вызове OC из JS
@param userContentController Информация о userContentController, настроенная в webview
@param message Сообщение, переданное при выполнении JS
*/
typedef void (^BAKit_webView_userContentControllerDidReceiveScriptMessageBlock)(WKUserContentController *userContentController, WKScriptMessage *message);
/**
Определяет, следует ли перейти на URL перед отправкой запроса. Если этот метод не добавлен, wkwebview не сможет перейти на AppStore или позвонить. Здесь обрабатывается перехват URL для дальнейшей обработки.
@param currentUrl Текущий URL
*/
typedef void (^BAKit_webView_decidePolicyForNavigationActionBlock)(NSURL *currentUrl);
/**
Получение текущего URL в webview
@param currentUrl currentUrl
*/
typedef void (^BAKit_webView_getCurrentUrlBlock)(NSURL *currentUrl);
/**
Получение текущей высоты webview
@param currentHeight currentHeight
*/
typedef void (^BAKit_webView_getCurrentHeightBlock)(CGFloat currentHeight);
```@interface WKWebView (BAKit)
<
WKNavigationDelegate,
WKUIDelegate,
WKScriptMessageHandler
>
/**
Может ли вернуться на предыдущую страницу
*/
@property (nonatomic, readonly) BOOL ba_web_canGoBack;
/**
Может ли перейти на следующую страницу
*/
@property (nonatomic, readonly) BOOL ba_web_canGoForward;
/**
URL-схема для перехвата, сначала установите это свойство, затем используйте ba_web_decidePolicyForNavigationActionBlock для обработки, см. пример
*/
@property(nonatomic, strong) NSString *ba_web_urlScheme;
/**
Необходимо ли автоматически устанавливать высоту
*/
@property (nonatomic, assign) BOOL ba_web_isAutoHeight;
@property(nonatomic, copy) BAKit_webView_didStartProvisionalNavigationBlock ba_web_didStartBlock;
@property(nonatomic, copy) BAKit_webView_didCommitNavigationBlock ba_web_didCommitBlock;
@property(nonatomic, copy) BAKit_webView_didFinishNavigationBlock ba_web_didFinishBlock;
@property(nonatomic, copy) BAKit_webView_didFailProvisionalNavigationBlock ba_web_didFailBlock;
@property(nonatomic, copy) BAKit_webView_isLoadingBlock ba_web_isLoadingBlock;
@property(nonatomic, copy) BAKit_webView_getTitleBlock ba_web_getTitleBlock;
@property(nonatomic, copy) BAKit_webView_userContentControllerDidReceiveScriptMessageBlock ba_web_userContentControllerDidReceiveScriptMessageBlock;
@property(nonatomic, copy) BAKit_webView_decidePolicyForNavigationActionBlock ba_web_decidePolicyForNavigationActionBlock;
@property(nonatomic, copy) BAKit_webView_getCurrentUrlBlock ba_web_getCurrentUrlBlock;
@property(nonatomic, copy) BAKit_webView_getCurrentHeightBlock ba_web_getCurrentHeightBlock;
#pragma mark - Public method
/**
Добавление делегата WKWebView, обратите внимание: используйте этот метод для добавления делегата, например:
BAKit_WeakSelf
[self.webView ba_web_initWithDelegate:weak_self.webView uIDelegate:weak_self.webView];
@param navigationDelegate навигационный делегат
@param uIDelegate UI делегат
*/
- (void)ba_web_initWithDelegate:(id<WKNavigationDelegate>)navigationDelegate
uIDelegate:(id<WKUIDelegate>)uIDelegate;
/**
Возвращает на предыдущую страницу
*/
- (void)ba_web_goBack;
```/**
* Переходит на следующую страницу
*/
- (void)ba_web_goForward;
/**
* Обновляет webView
*/
- (void)ba_web_reload;
/**
* Загружает webview
*
* @param request запрос NSURL URLRequest
*/
- (void)ba_web_loadRequest:(NSURLRequest *)request;
/**
* Загружает webview
*
* @param URL запрос URL
*/
- (void)ba_web_loadURL:(NSURL *)URL;
/**
* Загружает webview
*
* @param URLString запрос URLString
*/
- (void)ba_web_loadURLString:(NSString *)URLString;
/**
* Загружает локальную веб-страницу
*
* @param htmlName запрос локального HTML файла
*/
- (void)ba_web_loadHTMLFileName:(NSString *)htmlName;
/**
* Загружает локальный htmlString
*
* @param htmlString запрос локального htmlString
*/
- (void)ba_web_loadHTMLString:(NSString *)htmlString;
/**
* Вызов JS из OC, загружает js строку, например: код для адаптивной высоты:
// webView адаптивная высота
[self ba_web_stringByEvaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
// Получает высоту страницы и перезаписывает frame webview
self.ba_web_currentHeight = [result doubleValue];
CGRect frame = webView.frame;
frame.size.height = self.ba_web_currentHeight;
webView.frame = frame;
}];
*
* @param javaScriptString js строка
*/
- (void)ba_web_stringByEvaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id result, NSError * _Nullable error))completionHandler;
/**
JS вызывает OC, addScriptMessageHandler:name: имеет два параметра, первый параметр - это делегат userContentController, второй параметр - это объект, отправляющий postMessage в JS. Добавляет обработчик сообщений скрипта, при этом необходимо добавить window.webkit.messageHandlers.<name>.postMessage(<messageBody>) в JS.
@param nameArray массив объектов, отправляющих postMessage в JS, можно добавить несколько объектов одновременно
*/
- (void)ba_web_addScriptMessageHandlerWithNameArray:(NSArray *)nameArray;@end
NS_ASSUME_NONNULL_END
```### demo 示例
// Пример 1:
NSURL *url = [[NSBundle mainBundle] URLForResource:@"BAWebView" withExtension:@"html"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
```
```markdown
## Пример 4: Загрузка локального HTML файла
```objc
BAWebViewController *webVC = [BAWebViewController new];
webVC.title = self.dataArray[indexPath.row];
[webVC ba_web_loadHTMLFileName:@"BAHome"];
```
```[self.navigationController pushViewController:webVC animated:YES];
```
## Пример 5: Обмен данными между JS и OC
```objc
#import "ViewController2.h"
#import "BAKit_WebView.h"
@interface ViewController2 ()
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) UIButton *shareBtn;
@end
@implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = BAKit_Color_Gray_10;
self.shareBtn.hidden = NO;
self.webView.hidden = NO;
NSString *htmlName = @"BAHome2";
[self.webView ba_web_loadHTMLFileName:htmlName];
[self ba_JS_OC];
[self ba_OC_JS_2];
}
``````markdown
#pragma mark - JS_OC
- (void)ba_JS_OC {
// 1. Сначала регистрируем ID
NSArray *messageNameArray = @[@"BA_Alert", @"BA_JumpVC", @"BA_SendMsg"];
[self.webView ba_web_addScriptMessageHandlerWithNameArray:messageNameArray];
// 2. Когда JS вызывает OC, webview вызывает этот блок
BAKit_WeakSelf
self.webView.ba_web_userContentControllerDidReceiveScriptMessageBlock = ^(WKUserContentController * _Nonnull userContentController, WKScriptMessage * _Nonnull message) {
BAKit_StrongSelf
if ([message.name isEqualToString:messageNameArray[0]]) {
NSString *msg = @"Жизнь не прекращается, эксперименты продолжаются... От OC Alert!";
BAKit_ShowAlertWithMsg_ios8(msg);
} else if ([message.name isEqualToString:messageNameArray[1]]) {
UIViewController *vc = [UIViewController new];
vc.view.backgroundColor = BAKit_Color_Green;
vc.title = @"Это VC, на которое перешли с помощью кнопки JS";
[self.navigationController pushViewController:vc animated:YES];
} else if ([message.name isEqualToString:messageNameArray[2]]) {
NSArray *array = message.body;
NSString *msg = [NSString stringWithFormat:@"Это номер телефона БОА: %@, \n%@ !!", array[0], array[1]];
BAKit_ShowAlertWithMsg_ios8(msg);
}
};
}
``````markdown
#pragma mark - OC перехват JS URL обработки
- (void)ba_OC_JS_2
{
BAKit_WeakSelf
// Необходимо сначала установить URL scheme для перехвата, а затем обработать обратный вызов
self.webView.ba_web_urlScheme = @"basharefunction";
self.webView.ba_web_decidePolicyForNavigationActionBlock = ^(NSURL *currentUrl) {
BAKit_StrongSelf
// Проверяем, соответствует ли хост, и выполняем соответствующие действия
if ([currentUrl.host isEqualToString:@"shareClick"])
{
// Перехватываем содержимое URL для обмена
[self ba_shareClickWithUrl:currentUrl];
}
else if ([currentUrl.host isEqualToString:@"getLocation"])
{
[self ba_getLocationWithUrl:currentUrl];
}
};
}
``````markdown
#pragma mark OC перехват JS URL обработки: 1. Перехватываем содержимое обмена, предоставленное JS, и обрабатываем его с помощью метода OC
- (void)ba_shareClickWithUrl:(NSURL *)url
{
NSString *url_query = url.query;
NSArray *paramArray = [url_query componentsSeparatedByString:@"&"];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *dict_key in paramArray)
{
NSArray *dataArray = [dict_key componentsSeparatedByString:@"="];
if (dataArray.count > 1)
{
NSString *decode_value = [dataArray[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[dict setObject:decode_value forKey:dataArray[0]];
}
}
NSLog(@"Полученный из H5 параметр словарь: %@", dict);
/*!
Полученный из H5 параметр словарь:
{
content = "Добро пожаловать в версию 2.1 Болай Обмен";
imagePath = "Адрес изображения";
title = "Болай Обмен 2.1 версия";
url = "www.baidu.com";
}
*/
/*!
Общение с сервером и загрузка на сервер. Это тестовый пример, предполагается, что все параметры словаря загружаются на сервер.
*/
NSString *msg = [NSString stringWithFormat:@"Заголовок обмена: %@,\nСодержание: %@,\nURL изображения: %@,\nURL: %@", dict[@"title"], dict[@"content"], dict[@"imagePath"], dict[@"url"]];
BAKit_ShowAlertWithMsg_ios8(msg);
}
``````markdown
#pragma mark OC перехват JS URL обработки: 2. Перехват JS полученной информации о местоположении, обработка с помощью OC метода
- (void)ba_getLocationWithUrl:(NSURL *)url
{
NSString *url_query = url.query;
NSArray *paramArray = [url_query componentsSeparatedByString:@"&"];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *dict_key in paramArray)
{
NSArray *dataArray = [dict_key componentsSeparatedByString:@"="];
if (dataArray.count > 1)
{
``````markdown
#pragma mark - OC_JS
- (void)ba_OC_JS
{
// 3、OC 调用 JS
NSString *jsMethod = [NSString stringWithFormat:@"ba_insert('18566668888', '生命不息,折腾不止. . . 这里是 OC 插入 JS 的语句! ')"];
[self.webView ba_web_stringByEvaluateJavaScript:jsMethod completionHandler:^(id _Nullable result, NSError * _Nullable error) {
}];
}
- (void)ba_OC_JS_Process
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSArray *dataArray = @[@"latitude", @"longitude"];
for (int i = 0; i < dataArray.count; i += 2) {
NSString *decode_value = [dataArray[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[dict setObject:decode_value forKey:dataArray[0]];
}
NSLog(@"Полученный из H5 параметр словарь: %@", dict);
/*!
Полученный из H5 параметр словарь:
{
latitude = "23. 10486444538465";
longitude = "113. 37970297389353";
}
*/
NSString *msg = [NSString stringWithFormat:@"OC перехват【из JS полученного текущего местоположения】обработка\nШирота:%@\nДолгота:%@", dict[@"latitude"], dict[@"longitude"]];
BAKit_ShowAlertWithMsg_ios8(msg);
}
```
```markdown
# pragma mark - OC_JS
- (void)ba_OC_JS
{
// 3、OC 调用 JS
NSString *jsMethod = [NSString stringWithFormat:@"ba_insert('18566668888', '生命不息,折腾不止. . . 这里是 OC 插入 JS 的语句! ')"];
[self.webView ba_web_stringByEvaluateJavaScript:jsMethod completionHandler:^(id _Nullable result, NSError * _Nullable error) {
}];
}
```#pragma mark - OC кнопка вызова JS метода: 【JavaScriptCore库】!
- (IBAction)clickShareBtn:(UIButton *)sender
{
BAKit_WeakSelf
if (!self.webView.loading)
{
BAKit_StrongSelf
[self ba_OC_JS];
}
}
#pragma mark - JS вызов OC
- (void)ba_js_OCWithDictionary:(NSDictionary *)dict
{
if (![dict isKindOfClass:[NSDictionary class]])
{
return;
}
NSString *title = dict[@"title"];
NSString *content = dict[@"content"];
NSString *url = dict[@"url"];
// OC反馈给JS分享结果
NSString *result = [NSString stringWithFormat:@"ba_shareResult('%@', '%@', '%@')", title, content, url];
// OC вызов JS
[self.webView ba_web_stringByEvaluateJavaScript:result completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSLog(@"%@", error);
}];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
_webView.frame = CGRectMake(0, 80, BAKit_SCREEN_WIDTH, 300);
_shareBtn.frame = CGRectMake(50, BAKit_SCREEN_HEIGHT - 100, 150, 40);
}
#pragma mark - setter / getter
- (WKWebView *)webView
{
if (!_webView)
{
_webView = [WKWebView new];
// добавить WKWebView делегат, обратите внимание: используйте этот метод для добавления делегата
BAKit_WeakSelf
[self.webView ba_web_initWithDelegate:weak_self.webView uIDelegate:weak_self.webView];
_webView.backgroundColor = BAKit_Color_Yellow;
[self.view addSubview:_webView];
}
return _webView;
}
```- (UIButton *)shareBtn
{
if (!_shareBtn)
{
_shareBtn = [UIButton new];
[_shareBtn setTitle:@"OC кнопка вызова JS метода" forState:UIControlStateNormal];
[_shareBtn setTitleColor:BAKit_Color_Black forState:UIControlStateNormal];
_shareBtn.titleLabel.font = [UIFont systemFontOfSize:15];
_shareBtn.tag = 1001;
[_shareBtn setBackgroundColor:BAKit_Color_Green];
[_shareBtn addTarget:self action:@selector(clickShareBtn:) forControlEvents:UIControlEventTouchUpInside];
_shareBtn.titleLabel.textAlignment = NSTextAlignmentRight;
[self.view addSubview:_shareBtn];
}
return _shareBtn;
}```
## 5. Обновления: [в обратном порядке]Добро пожаловать к использованию [серии открытых кодов [BAHome]](https://github.com/BAHome)!
Для получения дополнительной информации перейдите на: [https://github.com/BAHome](https://github.com/BAHome)
### Последнее обновление: 28.09.2018 [в обратном порядке]
### Версия: [1.0.9]
### Обновления:
1.0.9.1. Исправлено отсутствие вызова обратного вызова метода блока после сетевых ошибок.
### Последнее обновление: 01.09.2017 [в обратном порядке]
### Версия: [1.0.8]
### Обновления:
1.0.8.1. В cell добавлено WK для идеального автоматического изменения высоты. Используйте свойство ba_web_isAutoHeight для автоматического получения высоты.
### Последнее обновление: 20.07.2017 [в обратном порядке]
### Версия: [1.0.7]
### Обновления:
1.0.7.1. Исправлен баг, связанный с неудачным освобождением данных в nameArray при взаимодействии JS и OC. Благодарим @Тан Хайян за отчет о баге!
### Последнее обновление: 14.07.2017 [в обратном порядке]
### Версия: [1.0.6]
### Обновления:
1.0.6.1. Добавлены некоторые переходные анимации.
### Последнее обновление: 07.07.2017 [в обратном порядке]
### Версия: [1.0.5]
### Обновления:
1.0.5.1. Добавлена возможность пользовательской модификации navigator.userAgent (см. demo BAWebViewController).### Последнее обновление: 05.07.2017 [в обратном порядке]
### Версия: [1.0.4]
### Обновления:
1.0.4.1. Исправлен баг, связанный с невозможностью отображения alert в WKWebView (см. demo5).
1.0.4.2. Добавлен пример демонстрации автоматического изменения высоты cell WKWebView (в demo есть небольшие оставшиеся проблемы для решения).
```## Последнее обновление: 17.06.2017 [в обратном порядке]
## Последняя версия: [Версия: 1.0.2]
### Обновления:
1.0.2.1. Добавлен перехват данных URL JS в OC, с подробным примером.
1.0.2.2. Улучшена структура кода.```## Последнее обновление: 15.06.2017 [в обратном порядке]
## Последняя версия: [Версия: 1.0.1]
### Обновления:
1.0.1.1. Поддержка iOS 8 и iOS 9.
## Последнее обновление: 15.06.2017 [в обратном порядке]
## Последняя версия: [Версия: 1.0.0]
### Обновления:
1.0.0.1. Классифицированная обертка для WKWebView без каких-либо вторжений в исходный код.
1.0.0.2. Реализация необходимых делегатных вызовов с помощью блоков, что делает код более удобным и компактным.
1.0.0.3. Одной строкой кода можно выполнить запросы для request, URL, URLString, локальных HTML-файлов, HTMLString и т.д.
1.0.0.4. Двумя строками кода можно организовать взаимодействие между JS и OC (на данный момент самый простой, быстрый и эффективный метод в git).
1.0.0.5. Одним блоком можно получить title, progress, currentURL, высоту текущей страницы и т.д.
1.0.0.6. Уже готовый BAWebViewController можно использовать сразу, а также можно использовать пример для создания собственного браузера [с примером].
1.0.0.7. Собственное запросное перехватывание данных для JS в WKWebView (с использованием классификации).
## 6. Отчет о багах
> 1. Если вы столкнулись с багами во время разработки, пожалуйста, сообщите нам о них [группа BAHome](https://github.com/BAHome). Мы обязательно будем внимательно относиться к каждому вопросу!>
> 2. Студенты, которые будут выдвигать требования и отслеживать ошибки, не забудьте предоставить нам ссылки на ваш git или блог, я добавлю прямые ссылки на ваши ресурсы! Надеемся на активное участие в тестировании!## 7. Члены команды BAHome
> 1. QQ-группа
479663605
[Обратите внимание: эта группа стоит 2 юаня, если вам это не подходит, не беспокойте нас!]
> Сун Боьянь
QQ: 137361770
git: [https://github.com/boai](https://github.com/boai)
Jianshu: [http://www.jianshu.com/u/95c9800fdf47](http://www.jianshu.com/u/95c9800fdf47)
Weibo: [](http://weibo.com/538298123)
> Ма Цзинли
QQ: 1253540493
git: [https://github.com/MaJingli](https://github.com/MaJingli)
> Лю Сяофэн
QQ: 442171865
git: [https://github.com/zeR0Lu](https://github.com/zeR0Lu)
> Чжень Цзи
QQ: 3161182978
git: [https://github.com/chenjipdc](https://github.com/chenjipdc)
Jianshu: [http://www.jianshu.com/u/90ae559fc21d](http://www.jianshu.com/u/90ae559fc21d)
> Рень Цзифэн
QQ: 459643690
git: [https://github.com/renzifeng](https://github.com/renzifeng)
> У Фушоун
QQ: 498121294
> Ши Шаоюн
QQ: 363605775
git: [https://github.com/CrazyCoderShi](https://github.com/CrazyCoderShi)
Jianshu: [http://www.jianshu.com/u/0726f4d689a3](http://www.jianshu.com/u/0726f4d689a3)
> Тан Хайяо
QQ: 790015339
git: [https://github.com/tanghaiyang1992](https://github.com/tanghaiyang1992)
Jianshu: [http://www.jianshu.com/u/b833cfd6bd58](http://www.jianshu.com/u/b833cfd6bd58)
## 8. Основная среда разработки и поддерживаемые версии
> Разработка ведется на последней версии Xcode, теоретически поддерживаются версии iOS 8 и выше. Если возникнут проблемы с совместимостью версий, пожалуйста, сообщите нам в кратчайшие сроки! Спасибо за сотрудничество!
## 9. Благодарности
> Благодарим команду BAHome за активное участие и сотрудничество. В будущем мы планируем выпустить серию утилит для обработки UI-контролов. Если у вас есть какие-либо требования, вы можете оставить их в разделе issue, и если они разумны, мы постараемся выпустить новые версии как можно скорее!> Развитие проекта BAHome невозможно без доверия и поддержки наших друзей. Спасибо всем за поддержку!
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )