回答編集履歴
1
実装例を提示
answer
CHANGED
@@ -3,4 +3,120 @@
|
|
3
3
|
|
4
4
|
同じ現象ではありませんが関連するteratailの質問とStackoverflowを貼っておきます。こちらは、表示が真っ白になったり遷移しなかったりという内容です。
|
5
5
|
- [iOS - swift WKWebViewで表示したブラウザのpdfファイルを開きたい|teratail](https://teratail.com/questions/209048)
|
6
|
-
- [iOS 13 WKWebView not showing pdf file anymore](https://stackoverflow.com/questions/58073513/ios-13-wkwebview-not-showing-pdf-file-anymore)
|
6
|
+
- [iOS 13 WKWebView not showing pdf file anymore](https://stackoverflow.com/questions/58073513/ios-13-wkwebview-not-showing-pdf-file-anymore)
|
7
|
+
|
8
|
+
----
|
9
|
+
Mar 11, 2020 追記
|
10
|
+
仕様固めに時間がかかってしまいました。
|
11
|
+
「いったんWebコンテンツを開くが、PDFのダウンロードリンクを開く場合がある」というシチュエーションで、当方では下記のように実装しました。ご参考になれば幸いです。
|
12
|
+
```objectivec
|
13
|
+
// MyWebViewController.h
|
14
|
+
#import <UIKit/UIKit.h>
|
15
|
+
#import <WebKit/WebKit.h>
|
16
|
+
#import <QuickLook/QuickLook.h>
|
17
|
+
|
18
|
+
NS_ASSUME_NONNULL_BEGIN
|
19
|
+
|
20
|
+
@interface MyWebViewController : UIViewController <WKNavigationDelegate, WKUIDelegate, QLPreviewControllerDataSource>
|
21
|
+
|
22
|
+
@property (nonatomic) NSString *firstUrl;
|
23
|
+
|
24
|
+
@end
|
25
|
+
|
26
|
+
NS_ASSUME_NONNULL_END
|
27
|
+
```
|
28
|
+
|
29
|
+
```objectivec
|
30
|
+
// MyWebViewController.m
|
31
|
+
|
32
|
+
@interface MyWebViewController()
|
33
|
+
|
34
|
+
@property (nonatomic) WKWebView *webView;
|
35
|
+
@property (nonatomic) NSString *previewFilePath;
|
36
|
+
|
37
|
+
@end
|
38
|
+
|
39
|
+
- (void)viewDidLoad {
|
40
|
+
[super viewDidLoad];
|
41
|
+
self.webView = [[WKWebView alloc] init];
|
42
|
+
self.webView.navigationDelegate = self;
|
43
|
+
self.webView.UIDelegate = self;
|
44
|
+
self.webView.translatesAutoresizingMaskIntoConstraints = false;
|
45
|
+
|
46
|
+
[self.view addSubview:self.webView];
|
47
|
+
// 制約の設定等は省略...
|
48
|
+
}
|
49
|
+
|
50
|
+
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
|
51
|
+
NSURL *url = navigationAction.request.URL;
|
52
|
+
if([url.absoluteString compare:self.firstUrl] == NSOrderdSame) {
|
53
|
+
decisionHandler(WKNavigationActionPolicyAllow);
|
54
|
+
return;
|
55
|
+
}
|
56
|
+
|
57
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
58
|
+
[[NSURLSession.sharedSession dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
59
|
+
if(error != nil || data == nil || data.length == 0) {
|
60
|
+
NSString *errorDescription = [@"ファイルのダウンロードに失敗しました。" stringByAppendingString:error.localizedDescription];
|
61
|
+
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"通信エラー" message:errorDescription preferredStyle:UIAlertControllerStyleAlert];
|
62
|
+
[alertController addAction:[UIAlertAction actionWithTitle:@"閉じる" style:UIAlertActionStyleDefault handler:nil]];
|
63
|
+
dispatch_async(dispatch_get_main_queue(),^{
|
64
|
+
[self presentViewController:alertController animated:YES completion:nil];
|
65
|
+
});
|
66
|
+
decisionHandler(WKNavigationActionPolicyCancel);
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
|
70
|
+
// PDF以外はとりあえず通すが何が起こっても知らない
|
71
|
+
NSHTTPURLResponse *res = (NSHTTPURLResponse*)response;
|
72
|
+
if([res.allHeaderFields[@"Content-Type"] compare:@"application/pdf"] != NSOrderedSame) {
|
73
|
+
decisionHandler(WKNavigationActionPolicyAllow);
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
|
77
|
+
NSString * __block filename = @"ダウンロードファイル";
|
78
|
+
[[(NSString*)res.allHeaderFields[@"Content-Disposition"] componentsSeparatedByString:@";"] enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
79
|
+
NSArray<NSString*> *pair = [[obj stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet] componentsSeparatedByString:@"="];
|
80
|
+
if([pair[0] compare:@"filename"] != NSOrderedSame) return;
|
81
|
+
filename = [pair[1] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
|
82
|
+
if([filename hasPrefix:@"\""]) filename = [filename substringFromIndex:1];
|
83
|
+
if([filename hasSuffix:@"\""]) filename = [filename substringToIndex:filename.length - 1];
|
84
|
+
}];
|
85
|
+
|
86
|
+
NSString *filePath = [[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/"] stringByAppendingPathComponent:filename];
|
87
|
+
[data writeToFile:filePath atomically:YES];
|
88
|
+
self.previewFilePath = filePath;
|
89
|
+
|
90
|
+
dispatch_async(dispatch_get_main_queue(),^{
|
91
|
+
MyQuickLookViewController* ql = [[MyQuickLookViewController alloc] init];
|
92
|
+
[self.navigationController pushViewController:ql animated:YES];
|
93
|
+
ql.dataSource = self;
|
94
|
+
[ql refreshCurrentPreviewItem];
|
95
|
+
});
|
96
|
+
|
97
|
+
decisionHandler(WKNavigationActionPolicyCancel);
|
98
|
+
}] resume];
|
99
|
+
});
|
100
|
+
}
|
101
|
+
|
102
|
+
// MARK: - QuickLook
|
103
|
+
- (void)presentQuickLookPreviewController {
|
104
|
+
dispatch_async(dispatch_get_main_queue(),^{
|
105
|
+
MyQuickLookViewController* ql = [[MyQuickLookViewController alloc] init];
|
106
|
+
[self.navigationController pushViewController:ql animated:YES];
|
107
|
+
ql.dataSource = self;
|
108
|
+
[ql refreshCurrentPreviewItem];
|
109
|
+
});
|
110
|
+
}
|
111
|
+
|
112
|
+
// MARK: QLPreviewControllerDataSource
|
113
|
+
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController*)previewController {
|
114
|
+
return 1;
|
115
|
+
}
|
116
|
+
|
117
|
+
/// プレビューするファイルのパスを NSURL で返す
|
118
|
+
- (id<QLPreviewItem>)previewController:(QLPreviewController*)controller previewItemAtIndex:(NSInteger)index {
|
119
|
+
NSURL *url = [NSURL fileURLWithPath:self.previewFilePath];
|
120
|
+
return url;
|
121
|
+
}
|
122
|
+
```
|