5

我需要连接到我的服务器以获取一些JSON数据,并且我必须同时支持iOS 6iOS 7.

我应该创建两个类吗?一个带有NSURLSessionforiOS 7一个带有NSURLConnectionfor iOS 6?还是我应该同时使用NSURLConnection它们?

4

4 回答 4

3

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

于 2013-10-16T14:47:52.393 回答
3

好问题。事实上,我有同样的问题并对其进行了相当多的研究,我认为这是使用协议(也称为其他语言的接口)的好地方。这是基于著名的“Gang of Four” Patterns Book 中的引用“Program to an interface, not an implementation”。我认为最好尝试为未来编写代码,所以如果他们决定弃用某些东西,我永远不会受到打击(这里不是这种情况,但你永远不知道)。

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

例如,您可以像这样创建服务器协议:

// 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

于 2014-04-15T17:51:15.907 回答
0

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

于 2013-10-17T22:00:01.383 回答
0

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

这些天,我会投票支持在 NSURLConnection 类实现周围使用编译器警告抑制的 TenaciousJay 解决方案。

#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);
于 2015-10-17T08:59:54.870 回答