Ios7 NSURLSession或NSURLConnection-支持iOS 6

Ios7 NSURLSession或NSURLConnection-支持iOS 6,ios7,nsurlconnection,nsurlsession,Ios7,Nsurlconnection,Nsurlsession,我需要连接到我的服务器以获取一些JSON数据,我必须同时支持ios6和ios7 我应该创建两个类吗?一个具有用于iOS 7的nsursession,一个具有用于iOS 6的nsurconnection?或者我应该对这两个类都使用NSURLConnection?创建两个独立的类来完成基本相同的任务,您会获得什么好处?如果您不能使用NSURLSession,因为它仅在iOS 7中受支持,并且您可以使用NSURLConnection获得相同的功能,这在两者中都适用,那么只需使用NSURLConnect

我需要连接到我的服务器以获取一些
JSON
数据,我必须同时支持
ios6
ios7


我应该创建两个类吗?一个具有用于iOS 7的
nsursession
,一个具有用于iOS 6的
nsurconnection
?或者我应该对这两个类都使用
NSURLConnection

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

如果必须使用
NSURLCredentialPersistenceForSession
如果必须进入Windows身份验证网络…则使用
NSURLConnection将为您带来多个问题。我现在正在经历痛苦,我已经得出结论,我需要两者来支持iOS 7。基本上,如果您使用
NSURLConnection
willSendRequestForAuthenticationChallenge
,您会发现在iOS 7中,您的会话将以自己的思维结束(似乎需要30秒的思维跨度)。因此,如果您必须保留凭证才能访问更多SOAP或其他内容,欢迎来到恐怖穹顶!如果我找到了一个顺利的解决方案,我会用代码向您报告。

好问题。事实上,我也有同样的问题,并且对它进行了大量的研究,我认为这是一个使用协议的好地方(在其他语言中称为接口)。这是根据著名的“四人帮”模式书中的“程序到接口,而不是实现”这句话编写的。我认为最好尝试为未来编写代码,这样,如果他们决定不推荐某件东西,我就不会受到打击(这里不是这样,但你永远不知道)

与其编写类,不如编写一个协议来定义要使用的方法,然后创建两个不同的类来实现这些方法。在您的应用程序中,您可以创建一个指针,指向实现所有协议方法的任何类,然后每个实现类都可以使用它们希望实现的任何框架/库/其他代码

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

// Server.h
@protocol Server <NSObject>
@required
- (void)callService:(NSString *)service withData:(NSData *)data;
@end
// 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
//Server.h
@协议服务器
@必需的
-(void)callService:(NSString*)带有数据的服务:(NSData*)数据;
@结束
然后创建一个RestServer类,如下所示:

// Server.h
@protocol Server <NSObject>
@required
- (void)callService:(NSString *)service withData:(NSData *)data;
@end
// 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
//RestServer.h
#导入“Server.h”
@接口RestServer:NSObject
@结束
//RestServer.m
#导入“RestServer.h”
@RestServer的实现
-(void)callService:(NSString*)带有数据的服务:(NSData*)数据{
//使用REST编写代码
}
@结束
然后创建另一个类,如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
//SoapServer.h
#导入“Server.h”
@接口SoapServer:NSObject
@结束
//SoapServer.m
#导入“SoapServer.h”
@SoapServer的实现
-(void)callService:(NSString*)带有数据的服务:(NSData*)数据{
//使用SOAP编写代码
}
@结束
将主应用程序编码为仅使用指向接口的指针,现在无需更改主代码即可交换类:

// 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]];
}
//SomeViewController.m
#导入“Server.h”
#导入“RestServer.h”
#导入“SoapServer.h”
…
-(void)someMethod(){
id-myServer;
如果([self-shouldUseSOAP])
myServer=[[SoapServer alloc]init];
其他的
myServer=[[RestServer alloc]init];
[myServer callService:@“loginUser”和数据:[self-getData]];
}
现在,您可以随时更改服务器类,而无需查找代码中调用callService:withData:的所有位置。这是编程到接口的好处

我使用Rest vs Soap是因为我认为更新到Objective-C的人可能会更好地理解这一点,但在您的情况下,您可能会使用ConnectionServer vs SessionServer或类似的东西


另一个关于接口/协议编程的好读物可以在这里找到:

在撰写本文时,NSURLConnection在OS X 10.11和iOS 9.0中已被弃用,但我的应用程序需要支持OS X 10.7和iOS 6。 因此,现在您必须为正在进行的项目使用NSURLSession,但也支持现在已弃用的NSURLConnection类,以支持旧版操作系统版本

这些天来,我会投票支持在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);

这正是我所想的,但是你不应该总是使用最新的类吗?或者这是我自己学到的一件坏事吗?在使用酷的新API和支持旧的操作系统之间总是有一个折衷的办法。当新的API让你不必做旧版本中必须做的额外工作时,它们是很棒的。但是如果实现新API意味着更多的工作(尤其是重复的工作),那么我就必须传递它。情况似乎并非如此……如果您需要持续会话,或者每次发出请求时都需要持续一个新会话,或者至少通过认证过程而不持续,这取决于您需要连接的时间。请查看此链接以查看一个好消息NSURL课程教程: