回答編集履歴

1

実装例を提示

2020/03/11 13:49

投稿

thyda.eiqau
thyda.eiqau

スコア2982

test CHANGED
@@ -9,3 +9,235 @@
9
9
  - [iOS - swift WKWebViewで表示したブラウザのpdfファイルを開きたい|teratail](https://teratail.com/questions/209048)
10
10
 
11
11
  - [iOS 13 WKWebView not showing pdf file anymore](https://stackoverflow.com/questions/58073513/ios-13-wkwebview-not-showing-pdf-file-anymore)
12
+
13
+
14
+
15
+ ----
16
+
17
+ Mar 11, 2020 追記
18
+
19
+ 仕様固めに時間がかかってしまいました。
20
+
21
+ 「いったんWebコンテンツを開くが、PDFのダウンロードリンクを開く場合がある」というシチュエーションで、当方では下記のように実装しました。ご参考になれば幸いです。
22
+
23
+ ```objectivec
24
+
25
+ // MyWebViewController.h
26
+
27
+ #import <UIKit/UIKit.h>
28
+
29
+ #import <WebKit/WebKit.h>
30
+
31
+ #import <QuickLook/QuickLook.h>
32
+
33
+
34
+
35
+ NS_ASSUME_NONNULL_BEGIN
36
+
37
+
38
+
39
+ @interface MyWebViewController : UIViewController <WKNavigationDelegate, WKUIDelegate, QLPreviewControllerDataSource>
40
+
41
+
42
+
43
+ @property (nonatomic) NSString *firstUrl;
44
+
45
+
46
+
47
+ @end
48
+
49
+
50
+
51
+ NS_ASSUME_NONNULL_END
52
+
53
+ ```
54
+
55
+
56
+
57
+ ```objectivec
58
+
59
+ // MyWebViewController.m
60
+
61
+
62
+
63
+ @interface MyWebViewController()
64
+
65
+
66
+
67
+ @property (nonatomic) WKWebView *webView;
68
+
69
+ @property (nonatomic) NSString *previewFilePath;
70
+
71
+
72
+
73
+ @end
74
+
75
+
76
+
77
+ - (void)viewDidLoad {
78
+
79
+ [super viewDidLoad];
80
+
81
+ self.webView = [[WKWebView alloc] init];
82
+
83
+ self.webView.navigationDelegate = self;
84
+
85
+ self.webView.UIDelegate = self;
86
+
87
+ self.webView.translatesAutoresizingMaskIntoConstraints = false;
88
+
89
+
90
+
91
+ [self.view addSubview:self.webView];
92
+
93
+ // 制約の設定等は省略...
94
+
95
+ }
96
+
97
+
98
+
99
+ - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
100
+
101
+ NSURL *url = navigationAction.request.URL;
102
+
103
+ if([url.absoluteString compare:self.firstUrl] == NSOrderdSame) {
104
+
105
+ decisionHandler(WKNavigationActionPolicyAllow);
106
+
107
+ return;
108
+
109
+ }
110
+
111
+
112
+
113
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
114
+
115
+ [[NSURLSession.sharedSession dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
116
+
117
+ if(error != nil || data == nil || data.length == 0) {
118
+
119
+ NSString *errorDescription = [@"ファイルのダウンロードに失敗しました。" stringByAppendingString:error.localizedDescription];
120
+
121
+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"通信エラー" message:errorDescription preferredStyle:UIAlertControllerStyleAlert];
122
+
123
+ [alertController addAction:[UIAlertAction actionWithTitle:@"閉じる" style:UIAlertActionStyleDefault handler:nil]];
124
+
125
+ dispatch_async(dispatch_get_main_queue(),^{
126
+
127
+ [self presentViewController:alertController animated:YES completion:nil];
128
+
129
+ });
130
+
131
+ decisionHandler(WKNavigationActionPolicyCancel);
132
+
133
+ return;
134
+
135
+ }
136
+
137
+
138
+
139
+ // PDF以外はとりあえず通すが何が起こっても知らない
140
+
141
+ NSHTTPURLResponse *res = (NSHTTPURLResponse*)response;
142
+
143
+ if([res.allHeaderFields[@"Content-Type"] compare:@"application/pdf"] != NSOrderedSame) {
144
+
145
+ decisionHandler(WKNavigationActionPolicyAllow);
146
+
147
+ return;
148
+
149
+ }
150
+
151
+
152
+
153
+ NSString * __block filename = @"ダウンロードファイル";
154
+
155
+ [[(NSString*)res.allHeaderFields[@"Content-Disposition"] componentsSeparatedByString:@";"] enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
156
+
157
+ NSArray<NSString*> *pair = [[obj stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet] componentsSeparatedByString:@"="];
158
+
159
+ if([pair[0] compare:@"filename"] != NSOrderedSame) return;
160
+
161
+ filename = [pair[1] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
162
+
163
+ if([filename hasPrefix:@"\""]) filename = [filename substringFromIndex:1];
164
+
165
+ if([filename hasSuffix:@"\""]) filename = [filename substringToIndex:filename.length - 1];
166
+
167
+ }];
168
+
169
+
170
+
171
+ NSString *filePath = [[NSHomeDirectory() stringByAppendingPathComponent:@"tmp/"] stringByAppendingPathComponent:filename];
172
+
173
+ [data writeToFile:filePath atomically:YES];
174
+
175
+ self.previewFilePath = filePath;
176
+
177
+
178
+
179
+ dispatch_async(dispatch_get_main_queue(),^{
180
+
181
+ MyQuickLookViewController* ql = [[MyQuickLookViewController alloc] init];
182
+
183
+ [self.navigationController pushViewController:ql animated:YES];
184
+
185
+ ql.dataSource = self;
186
+
187
+ [ql refreshCurrentPreviewItem];
188
+
189
+ });
190
+
191
+
192
+
193
+ decisionHandler(WKNavigationActionPolicyCancel);
194
+
195
+ }] resume];
196
+
197
+ });
198
+
199
+ }
200
+
201
+
202
+
203
+ // MARK: - QuickLook
204
+
205
+ - (void)presentQuickLookPreviewController {
206
+
207
+ dispatch_async(dispatch_get_main_queue(),^{
208
+
209
+ MyQuickLookViewController* ql = [[MyQuickLookViewController alloc] init];
210
+
211
+ [self.navigationController pushViewController:ql animated:YES];
212
+
213
+ ql.dataSource = self;
214
+
215
+ [ql refreshCurrentPreviewItem];
216
+
217
+ });
218
+
219
+ }
220
+
221
+
222
+
223
+ // MARK: QLPreviewControllerDataSource
224
+
225
+ - (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController*)previewController {
226
+
227
+ return 1;
228
+
229
+ }
230
+
231
+
232
+
233
+ /// プレビューするファイルのパスを NSURL で返す
234
+
235
+ - (id<QLPreviewItem>)previewController:(QLPreviewController*)controller previewItemAtIndex:(NSInteger)index {
236
+
237
+ NSURL *url = [NSURL fileURLWithPath:self.previewFilePath];
238
+
239
+ return url;
240
+
241
+ }
242
+
243
+ ```