iOS下载速度测试

今天分享一个下载速度测试的方法,很多APP都有测试网络延迟,测试下载上传速度。之前测试网络延迟的ping我们已经说过了,今天再来讲讲下载速度测试的办法。

基本想法

下载上传速度的测试,我的想法是下载一个静态资源,然后计算他的速度,这里使用AF来做下载,当然原生的NSURLSession也是一样的,为了方便,我就直接使用AF了

去百度上找一个静态资源:

http://sw.bos.baidu.com/sw-search-sp/software/d28b12c330f7b/android-studio-bundle_2.2.0.0.exe

Android studion

新建一个类,用于速度的测试PPSNetSpeedTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14

typedef void(^NetSpeedBlock)(NSString *speed);

@interface PPSNetSpeedTest : NSObject

/**
下载网速测试

@param callBackBlock 每秒回调,用于实时回传网速
@param completeBlock 最后测试完成,回调平均网速
*/
- (void)startDownLoadTestWithCallBlock:(NetSpeedBlock)callBackBlock completeBlock:(NetSpeedBlock)completeBlock;

@end

其中的NetSpeedBlock是每次速度的回调

方法startDownLoadTestWithCallBlock:completeBlock:分别回传了每秒的下载速度和最后的平均速度

在实现方法里

说一下,我计算每秒下载速度的思路,在AF中,有一个下载的NSProgress,在progress中有这个文件的总大小,和当前下载的大小,我进行一个timer重复操作,每秒执行一个方法,来计算速度,在每次下载progress更新的时候,我都记录上了当前完成的文件大小,然后在计算的时候,来计算这一秒下载多少文件,那就是速度了。

说太多,我上代码吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

- (void)startDownLoadTestWithCallBlock:(NetSpeedBlock)callBackBlock completeBlock:(NetSpeedBlock)completeBlock{
self.callBackBlock = callBackBlock;
self.completeBlock = completeBlock;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:FILE_PATH]];
self.downloadTask = [_urlManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
_completeFile = downloadProgress.completedUnitCount;
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSURL *downloadURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [downloadURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
NSLog(@"完成下载,然后删除文件");
NSString *filesTR = filePath.path;
if (_second<9) {
[self finishDownLoad];//网速太快,10秒内下载完毕
}
if ([[NSFileManager defaultManager] fileExistsAtPath:filesTR]) {
NSError *error;
[[NSFileManager defaultManager] removeItemAtURL:filePath error:&error];
}
}];
[self.downloadTask resume];
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(countTime) userInfo:nil repeats:YES];
[_timer fire];
_second = 0;
}

这里需要注意的一个问题 就是在文件下载完成后,测试结束,需要把文件删除掉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)countTime{
++ _second;
if (_second == 9) {
[self finishCurrentTest];
CGFloat averageSpeed = self.completeFile/(pow(1024, 2)*10.0);
self.completeBlock([NSString stringWithFormat:@"%.2fM",averageSpeed]);
self.completeBlock = nil;
[self.downloadTask cancel];
return;
}
NSInteger everySecondFile = self.completeFile - self.lastSecondCompleteFile;
CGFloat sppeed = everySecondFile/pow(1024, 2)*1.0;
self.callBackBlock([NSString stringWithFormat:@"%.2fM",sppeed]);
self.lastSecondCompleteFile = self.completeFile;
}

因为下载的文件都是以字节为单位,所以我转换成了M

pow(1024, 2) = 1024*1024

self.lastSecondCompleteFile = self.completeFile;

这句代码 是将每次计算完成之后,将lastSecondCompleteFile更新为此次下载的大小,等到下一秒,再来进行计算

非常重要的一点是,我们这里使用了timer,一定不要忘记,将timer invalidate

在下载完成,计算平均速度

1
2
3
4
5
6
7
8
9
- (void)finishDownLoad{
[self finishCurrentTest];
++ _second;
CGFloat averageSpeed = self.completeFile/(pow(1024, 2)*(_second+1)*1.0);
self.completeBlock([NSString stringWithFormat:@"%.2fM",averageSpeed]);
self.completeBlock = nil;
self.callBackBlock = nil;
[self.downloadTask cancel];
}
1
2
3
4
- (void)finishCurrentTest{
[_timer invalidate];
_timer = nil;
}
1
2
3
4
-(void)dealloc{
[_timer invalidate];
_timer = nil;
}

简单看一下效果

源代码

https://github.com/yangqian111/NetSpeedTest

欢迎大家关注我的公众号,我会定期分享一些我在项目中遇到问题的解决办法和一些iOS实用的技巧,现阶段主要是整理出一些基础的知识记录下来

上边是公众号,下边是我个人微信

文章也会同步更新到我的博客:
http://ppsheep.com