NSURLSession或NSURLConnection - iOS 6支持

时间:2013-10-16 14:40:53

标签: ios7 nsurlconnection nsurlsession

我需要与我的服务器建立连接以获取一些JSON数据,我必须同时支持iOS 6iOS 7

我应该创建两个类吗?一个NSURLSession iOS 7NSURLConnection iOS 6一个?或者我应该只使用NSURLConnection吗?

4 个答案:

答案 0 :(得分:3)

通过创建两个基本相同的单独类,您会获得什么好处?如果您不能使用NSURLSession,因为它仅在iOS 7中受支持,并且您可以使用同时适用于两者的NSURLConnection获得相同的功能,那么只需使用NSURLConnection即可。您将需要维护更少的代码。

答案 1 :(得分:3)

好问题。事实上,我有同样的问题,并对它进行了相当多的研究,我认为这是使用协议(其他语言中的a.k.a.界面)的好地方。这是基于着名的“四人帮”模式书中的“程序到界面而不是实现”的引用。我认为最好为将来尝试编码,所以如果他们决定弃用某些东西我就不会受到打击(这不是这种情况,但你永远不知道)。

编写一个定义要使用的方法的协议,然后创建两个实现这些方法的不同类,而不是编写类。在你的应用程序中,你将创建一个指针,指向任何实现所有协议方法的类,然后每个实现类可以使用他们想要发生的任何框架/库/其他代码。

例如,您可以创建如下的服务器协议:

// Server.h
@protocol Server <NSObject>
@required
- (void)callService:(NSString *)service withData:(NSData *)data;
@end

然后创建一个这样的RestServer类:

// RestServer.h
#import "Server.h"
@interface RestServer : NSObject <Server>
@end 

// RestServer.m
#import "RestServer.h"
@implementation RestServer
- (void)callService:(NSString *)service withData:(NSData *)data {
// Code using REST
}
@end

然后创建另一个类,如SoapServer:

// SoapServer.h
#import "Server.h"
@interface SoapServer : NSObject <Server>
@end 

// SoapServer.m
#import “SoapServer.h"
@implementation SoapServer
- (void)callService:(NSString *)service withData:(NSData *)data {
// Code using SOAP
}
@end

将您的主应用程序编码为只使用指向界面的指针,现在您可以交换类而无需更改主代码:

// SomeViewController.m
#import “Server.h”
#import “RestServer.h”
#import “SoapServer.h”
…
- (void)someMethod() {
    id<Server> myServer;

    if ([self shouldIUseSoap])
        myServer = [[SoapServer alloc] init];
    else
        myServer = [[RestServer alloc] init];

    [myServer callService:@"loginUser" withData:[self getData]];
}

现在,您可以随时更改服务器类,而无需在代码中调用callService:withData:的所有位置。这是对接口进行编程的好处!

我使用了Rest vs Soap,因为我认为Objective-C更新的人可能会更好地理解,但在你的情况下,你可能会有一个ConnectionServer vs SessionServer或类似的东西。

关于接口/协议编程的另一个好读物可以在这里找到:https://stackoverflow.com/a/384067/504873

答案 2 :(得分:0)

如果必须进入Windows身份验证网络,则必须使用NSURLCredentialPersistenceForSession ...然后使用NSURLConnection将为您创建多个问题。我现在正在经历痛苦并得出结论,我需要两者都支持iOS 7.基本上,如果你使用NSURLConnectionwillSendRequestForAuthenticationChallenge,你会发现在iOS 7中,你的会话将以自己的想法结束(似乎是30秒的思维范围)。因此,如果你必须坚持使用凭证来访问更多的SOAP或其他什么,欢迎来到恐怖的圆顶!如果我找到一个顺利的解决方案,我会用代码向您报告。

答案 3 :(得分:0)

在撰写本文时,NSURLConnection已在OS X 10.11和iOS 9.0中弃用,但我的Apps需要支持OS X 10.7和iOS 6。 因此,现在您必须将NSURLSession用于正在进行的项目,但也支持现已弃用的NSURLConnection类,以支持旧版OS!

我现在会投票支持TenaciousJay解决方案,并在NSURLConnection类实现中使用编译器警告抑制。

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
       /* NSURLConnection code here */
#pragma GCC diagnostic pop

通过创建两个基本相同的单独类,您将获得的好处是,当您最终可以放弃对旧版操作系统版本的支持时,您最终可以删除旧的,已弃用的解决方案。

我的代码决定使用一个类或另一个类不会基于某些类属性,而是基于宏的结果:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

适用于iOS或OS X:

NSString *systemVersion = nil;
        if ([[NSProcessInfo processInfo] respondsToSelector:NSSelectorFromString(@"operatingSystemVersion")]) {
            NSOperatingSystemVersion operatingSystemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
            systemVersion       = [NSString stringWithFormat:@"%ld.%ld.%ld", (long)operatingSystemVersion.majorVersion, (long)operatingSystemVersion.minorVersion, (long)operatingSystemVersion.patchVersion];
        } else {
            SInt32 versionMajor=0, versionMinor=0, versionPatch=0;
#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
            Gestalt(gestaltSystemVersionMajor, &versionMajor);
            Gestalt(gestaltSystemVersionMinor, &versionMinor);
            Gestalt(gestaltSystemVersionBugFix, &versionPatch);
#pragma GCC diagnostic pop
            systemVersion       = [NSString stringWithFormat:@"%ld.%ld.%ld", (long)versionMajor, (long)versionMinor, (long)versionPatch];
        }
        NSLog(@"[Line %d] %s OS X Runtime Version: '%@'", __LINE__, __PRETTY_FUNCTION__, systemVersion);