MST

星途 面试题库

面试题:Objective-C实现复杂业务场景下iOS网络请求与数据交互的架构设计

假设你要开发一个电商类的iOS应用,涉及商品展示、用户登录、下单支付等复杂业务场景,使用Objective-C进行网络请求与数据交互。请设计一个完整的网络层架构,包括如何封装网络请求、如何处理不同类型的响应以及如何确保数据的安全性和一致性,并详细说明设计思路和各模块的职责。
30.5万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

网络层架构设计

一、设计思路

  1. 模块化设计:将网络请求相关功能进行模块化拆分,每个模块负责特定的功能,提高代码的可维护性和可扩展性。
  2. 分层架构:采用分层架构,将网络层分为请求层、响应处理层和数据存储层,各层之间职责明确,降低耦合度。
  3. 数据安全与一致性:通过使用 HTTPS 协议确保数据传输安全,采用缓存机制保证数据一致性,并在数据处理过程中进行数据校验。

二、模块职责与实现

(一)请求层

  1. 请求封装类(NetworkRequest
    • 职责:负责封装各类网络请求,包括商品展示请求、用户登录请求、下单支付请求等。为每个业务场景提供统一的请求接口,隐藏底层网络请求细节。
    • 实现
@interface NetworkRequest : NSObject

// 商品展示请求
+ (void)fetchProductsWithCompletion:(void (^)(NSArray *products, NSError *error))completion;

// 用户登录请求
+ (void)loginWithUsername:(NSString *)username password:(NSString *)password completion:(void (^)(User *user, NSError *error))completion;

// 下单支付请求
+ (void)placeOrder:(Order *)order completion:(void (^)(BOOL success, NSError *error))completion;

@end

@implementation NetworkRequest

+ (void)fetchProductsWithCompletion:(void (^)(NSArray *products, NSError *error))completion {
    // 创建 URLRequest
    NSURL *url = [NSURL URLWithString:@"https://your-api.com/products"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"GET";

    // 发起网络请求
    NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            completion(nil, error);
            return;
        }

        // 处理响应数据
        if (data) {
            NSError *jsonError;
            NSArray *products = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
            if (jsonError) {
                completion(nil, jsonError);
            } else {
                completion(products, nil);
            }
        }
    }];
    [task resume];
}

// 其他请求方法类似实现
@end

(二)响应处理层

  1. 响应解析类(ResponseParser
    • 职责:负责解析不同类型的网络响应数据,将其转换为业务层可理解的数据模型。针对不同的业务请求,提供相应的解析方法。
    • 实现
@interface ResponseParser : NSObject

// 解析商品展示响应数据
+ (NSArray *)parseProductResponse:(NSData *)data error:(NSError **)error;

// 解析用户登录响应数据
+ (User *)parseLoginResponse:(NSData *)data error:(NSError **)error;

// 解析下单支付响应数据
+ (BOOL)parseOrderResponse:(NSData *)data error:(NSError **)error;

@end

@implementation ResponseParser

+ (NSArray *)parseProductResponse:(NSData *)data error:(NSError **)error {
    NSError *jsonError;
    NSArray *products = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
    if (jsonError) {
        if (error) {
            *error = jsonError;
        }
        return nil;
    }
    // 进一步将 JSON 数据转换为 Product 模型数组
    NSMutableArray *productModels = [NSMutableArray array];
    for (NSDictionary *productDict in products) {
        Product *product = [[Product alloc] initWithDictionary:productDict];
        [productModels addObject:product];
    }
    return productModels;
}

// 其他解析方法类似实现
@end
  1. 响应验证类(ResponseValidator
    • 职责:对解析后的响应数据进行有效性验证,确保数据符合业务规则。例如,验证用户登录响应中的用户信息是否完整,商品展示响应中的商品数据是否有效等。
    • 实现
@interface ResponseValidator : NSObject

// 验证商品展示响应数据
+ (BOOL)validateProductResponse:(NSArray *)products error:(NSError **)error;

// 验证用户登录响应数据
+ (BOOL)validateLoginResponse:(User *)user error:(NSError **)error;

// 验证下单支付响应数据
+ (BOOL)validateOrderResponse:(BOOL)success error:(NSError **)error;

@end

@implementation ResponseValidator

+ (BOOL)validateProductResponse:(NSArray *)products error:(NSError **)error {
    if (!products || products.count == 0) {
        if (error) {
            *error = [NSError errorWithDomain:@"ResponseValidationError" code:1 userInfo:@{NSLocalizedDescriptionKey:@"No products in response"}];
        }
        return NO;
    }
    return YES;
}

// 其他验证方法类似实现
@end

(三)数据存储层

  1. 缓存管理类(CacheManager
    • 职责:负责管理网络请求数据的缓存,以提高应用的性能和数据一致性。缓存数据可以根据业务需求设置合适的缓存策略,如缓存过期时间等。
    • 实现
@interface CacheManager : NSObject

// 获取商品缓存数据
+ (NSArray *)cachedProducts;

// 缓存商品数据
+ (void)cacheProducts:(NSArray *)products;

// 获取用户登录缓存数据
+ (User *)cachedUser;

// 缓存用户登录数据
+ (void)cacheUser:(User *)user;

@end

@implementation CacheManager

static NSMutableDictionary *cacheDict;

+ (void)initialize {
    cacheDict = [NSMutableDictionary dictionary];
}

+ (NSArray *)cachedProducts {
    return cacheDict[@"products"];
}

+ (void)cacheProducts:(NSArray *)products {
    cacheDict[@"products"] = products;
}

// 其他缓存方法类似实现
@end
  1. 数据持久化类(DataPersistence
    • 职责:对于一些需要持久化存储的数据,如用户登录信息等,负责将其保存到本地存储(如 Keychain、Core Data 等),以确保用户下次打开应用时无需重新登录等操作。
    • 实现:以 Keychain 存储用户登录信息为例
#import <Security/Security.h>

@interface DataPersistence : NSObject

// 保存用户登录信息到 Keychain
+ (BOOL)saveUserLoginInfo:(User *)user;

// 从 Keychain 获取用户登录信息
+ (User *)fetchUserLoginInfo;

@end

@implementation DataPersistence

+ (BOOL)saveUserLoginInfo:(User *)user {
    NSDictionary *query = @{
        (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
        (__bridge id)kSecAttrAccount: user.username,
        (__bridge id)kSecValueData: [user.password dataUsingEncoding:NSUTF8StringEncoding]
    };

    OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
    return status == errSecSuccess;
}

+ (User *)fetchUserLoginInfo {
    NSDictionary *query = @{
        (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
        (__bridge id)kSecAttrAccount: @"your_username_key",
        (__bridge id)kSecReturnData: (__bridge id)kCFBooleanTrue,
        (__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne
    };

    CFDataRef passwordData = NULL;
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&passwordData);
    if (status == errSecSuccess && passwordData) {
        NSString *password = [[NSString alloc] initWithData:(__bridge NSData *)passwordData encoding:NSUTF8StringEncoding];
        CFRelease(passwordData);
        User *user = [[User alloc] initWithUsername:@"your_username_key" password:password];
        return user;
    }
    return nil;
}
@end

三、数据安全性与一致性保证

  1. 数据传输安全:在网络请求中,使用 HTTPS 协议进行数据传输,iOS 系统的 NSURLSession 对 HTTPS 有很好的支持,默认会验证服务器证书的有效性,防止中间人攻击。
  2. 数据一致性
    • 缓存机制:通过 CacheManager 管理缓存数据,在网络请求成功后,将数据缓存起来。下次请求相同数据时,先从缓存中获取,如果缓存数据未过期且有效,则直接使用缓存数据,提高应用响应速度和数据一致性。
    • 数据校验:在响应处理层,通过 ResponseValidator 对解析后的响应数据进行严格的有效性验证,确保数据符合业务规则,避免因异常数据导致应用出现错误或不一致的情况。同时,在数据持久化存储时,也进行相应的数据校验,保证本地存储数据的一致性。