gpt4 book ai didi

ios - 如何在 iOS Reachability 中检测网络信号强度

转载 作者:技术小花猫 更新时间:2023-10-29 10:13:04 26 4
gpt4 key购买 nike

我正在 iOS 中创建一个新的旅行应用程序,这个应用程序高度依赖于 map ,并且将包含两个 map 。

  1. My first Map will work when the user has a strong Network Signal (Apple Maps).
  2. My second Map will be used when their isn't any Network or really Low signal (Offline MapBox).

为什么我在一个应用程序中有两个不同的 map ?我的应用程序是一个方向应用程序,所以当用户的网络非常低或没有网络时,它将转到离线 map MapBox。此外,Apple map 将集成 Yelp 而不是离线 map MapBox

所以我的问题是:如何检测 WiFi、4G Lte 和 3G 中的网络信号。 MapBox Offline Image

最佳答案

我最初的想法是对文件的下载进行计时,看看需要多长时间:

@interface ViewController () <NSURLSessionDelegate, NSURLSessionDataDelegate>

@property (nonatomic) CFAbsoluteTime startTime;
@property (nonatomic) CFAbsoluteTime stopTime;
@property (nonatomic) long long bytesReceived;
@property (nonatomic, copy) void (^speedTestCompletionHandler)(CGFloat megabytesPerSecond, NSError *error);

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

[self testDownloadSpeedWithTimout:5.0 completionHandler:^(CGFloat megabytesPerSecond, NSError *error) {
NSLog(@"%0.1f; error = %@", megabytesPerSecond, error);
}];
}

/// Test speed of download
///
/// Test the speed of a connection by downloading some predetermined resource. Alternatively, you could add the
/// URL of what to use for testing the connection as a parameter to this method.
///
/// @param timeout The maximum amount of time for the request.
/// @param completionHandler The block to be called when the request finishes (or times out).
/// The error parameter to this closure indicates whether there was an error downloading
/// the resource (other than timeout).
///
/// @note Note, the timeout parameter doesn't have to be enough to download the entire
/// resource, but rather just sufficiently long enough to measure the speed of the download.

- (void)testDownloadSpeedWithTimout:(NSTimeInterval)timeout completionHandler:(nonnull void (^)(CGFloat megabytesPerSecond, NSError * _Nullable error))completionHandler {
NSURL *url = [NSURL URLWithString:@"http://insert.your.site.here/yourfile"];

self.startTime = CFAbsoluteTimeGetCurrent();
self.stopTime = self.startTime;
self.bytesReceived = 0;
self.speedTestCompletionHandler = completionHandler;

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
configuration.timeoutIntervalForResource = timeout;
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
[[session dataTaskWithURL:url] resume];
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
self.bytesReceived += [data length];
self.stopTime = CFAbsoluteTimeGetCurrent();
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
CFAbsoluteTime elapsed = self.stopTime - self.startTime;
CGFloat speed = elapsed != 0 ? self.bytesReceived / (CFAbsoluteTimeGetCurrent() - self.startTime) / 1024.0 / 1024.0 : -1;

// treat timeout as no error (as we're testing speed, not worried about whether we got entire resource or not

if (error == nil || ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorTimedOut)) {
self.speedTestCompletionHandler(speed, nil);
} else {
self.speedTestCompletionHandler(speed, error);
}
}

@end

请注意,这衡量的是速度,包括启动连接的延迟。您也可以在 didReceiveResponse 中初始化 startTime ,如果您想排除初始延迟。


这样做之后,回想起来,我不喜欢花时间或带宽下载对应用程序没有实际好处的东西。因此,作为替代方案,我可能会建议一种更实用的方法:您为什么不尝试打开 MKMapView 并查看完成 map 下载需要多长时间?如果失败或花费的时间超过一定时间,请切换到离线 map 。同样,这里有相当多的可变性(不仅因为网络带宽和延迟,还因为一些 map 图像似乎被缓存),所以确保设置一个足够大的 kMaximumElapsedTime处理成功连接的所有合理排列(即,不要过于激进地使用低值)。

为此,只需确保将 View Controller 设置为 MKMapViewdelegate。然后你可以这样做:

@interface ViewController () <MKMapViewDelegate>
@property (nonatomic, strong) NSDate *startDate;
@end

static CGFloat const kMaximumElapsedTime = 5.0;

@implementation ViewController

// insert the rest of your implementation here

#pragma mark - MKMapViewDelegate methods

- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView {
NSDate *localStartDate = [NSDate date];
self.startDate = localStartDate;

double delayInSeconds = kMaximumElapsedTime;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// Check to see if either:
// (a) start date property is not nil (because if it is, we
// finished map download); and
// (b) start date property is the same as the value we set
// above, as it's possible this map download is done, but
// we're already in the process of downloading the next
// map.

if (self.startDate && self.startDate == localStartDate)
{
[[[UIAlertView alloc] initWithTitle:nil
message:[NSString stringWithFormat:@"Map timed out after %.1f", delayInSeconds]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}
});
}

- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error {
self.startDate = nil;

[[[UIAlertView alloc] initWithTitle:nil
message:@"Online map failed"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}

- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
NSTimeInterval elapsed = [[NSDate date] timeIntervalSinceDate:self.startDate];
self.startDate = nil;
self.statusLabel.text = [NSString stringWithFormat:@"%.1f seconds", elapsed];
}

关于ios - 如何在 iOS Reachability 中检测网络信号强度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14532651/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com