- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在我所有的 iOS 应用程序中,我都使用这种方法来尊重 MVC,我想确保我的实现是正确的,并且尊重最佳实践和 MVC 设计模式:
作为网络调用 API 的 AFNetworking 单例:
MyAPI.h :
#import "AFHTTPSessionManager.h"
#import "AFNetworking.h"
@interface MyAPI : AFHTTPSessionManager
+(MyAPI *)sharedInstance;
@end
MyAPI.m :
#pragma mark - Singleton
+(MyAPI*)sharedInstance
{
static MyAPI *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyAPI alloc] initWithBaseURL:[NSURL URLWithString:kROOT_URL]];
});
return sharedInstance;
}
使用单例来获取用户数据的模型用户(作为实现好吗?):
用户.h
@interface User : NSObject
@property (strong,nonatomic) NSString *userId;
@property (strong,nonatomic) NSString *email;
@property (strong,nonatomic) NSString *password;
-(id) initWithDictionary: (NSDictionary *) dictionay;
+(BOOL) isConnected;
+(void) disconnect;
+(NSString *) idOfConnectedUser;
+(User *) connectedUser;
+(void) loginWith : (NSString *) email andPassword :(NSString *) password complete:(void(^)(id result, NSError *error))block;
+(void) searchUsersFrom : (NSString *) countryCode withName :(NSString *) name andLevel:(NSString *) levelCode complete: (void(^)(id result, NSError *error)) block;
+(void) signup:(void(^)(id result, NSError *error)) block;
+(void) getUserFriends:(void(^)(id result, NSError *error)) block;
@end
用户.m
[......]
+(void) loginWith : (NSString *) email andPassword :(NSString *) password complete: (void(^)(id result, NSError *error)) block
{
__block NSString * result ;
NSDictionary *params = @{@"email": email, @"password": password};
[[MyAPI sharedInstance] POST:@"auth/" parameters:params success:^(NSURLSessionDataTask *task, id responseObject)
{
if([responseObject objectForKey:@"id"])
{
[[NSUserDefaults standardUserDefaults] setObject:(NSDictionary*) responseObject forKey:USER_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
result = [responseObject objectForKey:@"id"];
}
else
{
result = nil ;
}
if (block) block(result, nil);
} failure:^(NSURLSessionDataTask *task, NSError *error)
{
if (block) block(nil, error);
}];
}
[.....]
登录 Controller .m :
-(void)loginButtonAction:(UIButton *)sender
{
[......]
[ User loginWith:text andPassword:text complete:^(id result, NSError *error)
{
if (result)
{
[APPDELEGATE start];
}
else
{
// ERROR
}
}];
}
那么我的实现是否尊重 MCV 并遵循最佳实践,如果不尊重我该如何改进?
最佳答案
单例:您可能希望避免使用单例,它将帮助您改进 API 设计并使代码更易于测试。此外,在 User
的情况下,假设您希望支持更改用户(注销/ guest 用户/等)。使用当前方法,您将仅限于发送 NSNotification
,因为使用 connectedUser
的每个人都不知道底层引用已更改。
事件记录:您对能够执行网络的模型 User
所做的操作有点类似于 active record approach当您的模型变得更加复杂并且它可以执行的操作数量增加时,它可能无法很好地扩展。考虑将它们分成纯模型和实际执行网络的服务(或您将来需要的任何其他内容)。
模型序列化:考虑将模型和网络响应序列化逻辑封装到一个单独的类中(例如 LoginResponse
,除其他外,它指向 User
)框架,如 Mantle让它变得更容易。
MVC:根据我在 iOS MVC 中的经验,除了简单的应用程序之外,MVC 可能不是最佳方法。使用 MVC 的趋势是将所有逻辑放入您的 ViewController
中,使其变得非常庞大且难以维护。考虑其他模式,例如 MVVM
总而言之,我知道很难一次学习所有新技术,但您绝对可以从确保每个类执行一件事且仅执行一件事开始:模型不进行联网或持久化到磁盘, API 客户端不会反序列化每个响应或将数据保存到 NSUserDefaults
, View Controller 除了监听用户事件(按钮点击等)外什么都不做。如果将新开发人员引入您的代码库,仅此一项就可以使您的代码更易于推理和遵循。
希望对您有所帮助!
关于ios - 使用 AFNetworking 在 objective-c 中的模型对象内部获取远程数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30855777/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!