菜鸟教程小白 发表于 2022-12-12 09:30:36

ios - AFNetworking 2.0 + UIProgressView 如何正确显示上传 session 的进度


                                            <p><p>我正在使用 AFHTTPSessionManager 子类通过网络服务下载和上传数据。除了上传进度 View 之外,一切似乎都运行良好,我使用的是 UIProgressView+AFNetworking 类别。<br/>
代码是这样设置的:<br/></p>

<pre><code> NSURLSessionTask * task = [ addMediaWithURI:self.filePath success:^(NSURLSessionDataTask *task, BOOL added) {
      if (added) {
            NSLog(@&#34;Operation succ&#34;);
      }
      weakSelf.progressContainerView.hidden = YES;
    } orFailure:^(NSURLSessionDataTask *task, NSError *error) {
      weakSelf.progressContainerView.hidden = YES;
    }];
    self.progressContainerView.hidden = NO;
    ;
</code></pre>

<p><br/>
该方法直接调用:</p>

<pre><code>session = [self POST:ApiPostURL parameters:parameters constructingBodyWithBlock:^(id&lt;AFMultipartFormData&gt; formData) {
             name: ParameterMultimedia error:appendError];
      } success:^(NSURLSessionDataTask *task, id responseObject) {
            NSLog(@&#34;%@&#34;, responseObject);
            if ( isEqualToString:@&#34;ko&#34;]) {
                NSError * error = ;
                failure(task, error);
                return ;
            }
            success (task, YES);
      } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@&#34;%@&#34;, error);
            failure(task, error);
      }];
</code></pre>

<p>一旦我附加了进度 View ,如果我 checkin 它的方法,我可以确定它正确地观察了方法中的任务进度:</p>

<pre><code>- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(__unused NSDictionary *)change
                     context:(void *)context &lt;br&gt;
</code></pre>

<p>问题是 <code>if ( > 0)</code> 总是 false 因为 <code>countOfBytesExpectedToSend</code> 为 0,阅读有关 <code>NSURLSession</code> 的文档苹果表示:<br/></p>

<blockquote>
<p>Discussion The URL loading system can determine the length of the
upload data in three ways:</p>

<p>From the length of the NSData object provided as the upload body. From
the length of the file on disk provided as the upload body of an
upload task (not a download task). From the Content-Length in the
request object, if you explicitly set it</p>
</blockquote>

<p>如果我从请求 header<code>Content-Leght</code> 的请求中打印值,我会得到一个有效值:</p>

<pre><code>&#34;Accept-Language&#34; = &#34;it;q=1, en;q=0.9, fr;q=0.8, de;q=0.7, ja;q=0.6, nl;q=0.5&#34;;
&#34;Content-Length&#34; = 232172;
&#34;Content-Type&#34; = &#34;multipart/form-data; boundary=Boundary+357828FACC07BFAC&#34;;
&#34;User-Agent&#34; = &#34;XXXXX/1.0 (iPad; iOS 7.1; Scale/1.00)&#34;;
</code></pre>

<p>我不明白为什么总是返回等于 0 的值。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>Googleing,githubbing,我找到了答案,本质上这是 NSURLSession 的“功能”,当您使用 uploadstream 创建 session 时,任务会接管您设置的标题。由于在流中没有真正的内容大小,如果我们设置一些东西,任务将重写它。
<br/>
幸运的是 NSURLSession 有两个请求属性 <code>currentRequest</code>(被覆盖的)和 <code>originalRequest</code>。原始请求将继续保留我们的 <code>Content-Length</code>。 <br/>
我对 UIProgressView+AFNetworking 类别做了一些修改,以使其使用设置的内容长度工作,最好再检查一下是否有流。 <br/></p>

<pre><code>- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(__unused NSDictionary *)change
                     context:(void *)context
{
#if __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 70000
    if (context == AFTaskCountOfBytesSentContext || context == AFTaskCountOfBytesReceivedContext) {
      if () {

            //upload content length issue
//            if ( &gt; 0) {
            NSInteger byteToSend = [[ valueForHTTPHeaderField:@&#34;Content-Length&#34;] integerValue];
            if (byteToSend){
                dispatch_async(dispatch_get_main_queue(), ^{
                   / (byteToSend * 1.0f) animated:self.af_uploadProgressAnimated];
//                   / ( * 1.0f) animated:self.af_uploadProgressAnimated];
                });
            }
      }

      if () {
            if ( &gt; 0) {
                dispatch_async(dispatch_get_main_queue(), ^{
                   / ( * 1.0f) animated:self.af_downloadProgressAnimated];
                });
            }
      }

      if () {
            if ([(NSURLSessionTask *)object state] == NSURLSessionTaskStateCompleted) {
                @try {
                  ;

                  if (context == AFTaskCountOfBytesSentContext) {
                        ;
                  }

                  if (context == AFTaskCountOfBytesReceivedContext) {
                        ;
                  }
                }
                @catch (NSException * __unused exception) {}
            }
      }
    }
#endif
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - AFNetworking 2.0 &#43; UIProgressView 如何正确显示上传 session 的进度,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/23193983/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/23193983/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - AFNetworking 2.0 &#43; UIProgressView 如何正确显示上传 session 的进度