回答編集履歴
1
実装例を提示
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
|
+
```
|