私はウェブブラウザを作っています。URLテキストバーとWebViewを作成しました。しかし、私は常に、ロードされたWebページの量をユーザーに通知するプログレス/ロードバーを作成する方法を知りたいと思っていました。これを行うにはどうすればよいですか?
AppleのWebKit開発ガイドを確認しましたが、バーの読み込みについては何も説明していません。
@property
これは、Web ビュー、URL テキスト フィールド、進行状況インジケーターがあると仮定した場合の実際の実装です。
コントローラーは、リソース デリゲートおよびポリシー デリゲートである必要があります。
- (void)awakeFromNib
{
self.webView.resourceLoadDelegate = self;
self.webView.policyDelegate = self;
}
URL フィールドにページと同じ URL が含まれていることを確認してください。後で追跡するためにこれを使用します。
- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
{
self.urlField.stringValue = request.URL.absoluteString;
[listener use];
}
ページの読み込み開始を検出します。
- (id)webView:(WebView *)sender identifierForInitialRequest:(NSURLRequest *)request fromDataSource:(WebDataSource *)dataSource
{
if ([request.URL.absoluteString isEqualToString:self.urlField.stringValue]) {
[self.loadProgress setIndeterminate:YES];
[self.loadProgress startAnimation:self];
}
return [[NSUUID alloc] init];
}
これは、新しいデータが入ってくると呼び出されます。「長さ」パラメータは、このデータのチャンクで受信した長さであることに注意してください。これまでに受け取った実際の金額を確認するには、dataSource を使用する必要があります。また、ほとんどの Web サーバー (ほぼすべての動的 Web ページなど) は content-length ヘッダーを返さないため、大雑把な推測が必要になることにも注意してください。
- (void)webView:(WebView *)sender resource:(id)identifier didReceiveContentLength:(NSInteger)length fromDataSource:(WebDataSource *)dataSource
{
// ignore requests other than the main one
if (![dataSource.request.URL.absoluteString isEqualToString:self.urlField.stringValue])
return;
// calculate max progress bar value
if (dataSource.response.expectedContentLength == -1) {
self.loadProgress.maxValue = 80000; // server did not send "content-length" response. Pages are often about this size... better to guess the length than show no progres bar at all.
} else {
self.loadProgress.maxValue = dataSource.response.expectedContentLength;
}
[self.loadProgress setIndeterminate:NO];
// set current progress bar value
self.loadProgress.doubleValue = dataSource.data.length;
}
そして、このデリゲート メソッドは、リクエストの読み込みが完了すると呼び出されます。
- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource
{
// ignore requests other than the main one
if (![dataSource.request.URL.absoluteString isEqualToString:self.urlField.stringValue])
return;
[self.loadProgress stopAnimation:self];
}
Apple には、このページに読み込まれるリソースを追跡する方法の例があります。
どれだけ多くのリソースが残っているかを印刷する代わりに、数字を使用して進行状況バーを設定できます。
ところで: このカウントは、特定のページ/URL の読み込みが本当に終了したかどうかを確認する唯一の方法のようです。