AFNetworking 二次封装

本文介绍了一个针对iOS应用网络请求的二次封装方案,利用BJAppClient与BJHTTPSession类实现GET与POST请求,并提供取消请求的功能。同时,还实现了网络状态监测及根据不同网络状况给出提示。

  1. @interface BJAppClient AFHTTPSessionManager  
  2.   
  3. (instancetype)sharedClient;  
  4.   
  5. @end  

[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static NSString const APIBaseURLString @"xxxxx";  
  2.   
  3. @implementation BJAppClient  
  4.   
  5. (instancetype)sharedClient  
  6.  
  7.     static BJAppClient *_sharedClient nil;  
  8.     static dispatch_once_t onceToken;  
  9.     dispatch_once(&onceToken, ^{  
  10.   
  11.         _sharedClient [[BJAppClient alloc] initWithBaseURL:[NSURL URLWithString:APIBaseURLString]];    
  12.           
  13.     });  
  14.       
  15.     return _sharedClient;  
  16.  
  17.   
  18. #pragma mark 重写initWithBaseURL  
  19.   
  20.   
  21. -(instancetype)initWithBaseURL:(NSURL *)url  
  22.  
  23.     if (self [super initWithBaseURL:url])  
  24.           
  25.         self.requestSerializer.timeoutInterval 3;  
  26.           
  27.         self.requestSerializer.cachePolicy NSURLRequestReloadIgnoringLocalCacheData;  
  28.           
  29.         self.requestSerializer [AFHTTPRequestSerializer serializer];  
  30.         AFJSONResponseSerializer response [AFJSONResponseSerializer serializer];  
  31.         response.removesKeysWithNullValueYES;  
  32.         self.responseSerializer response;  
  33.           
  34.   
  35.           
  36.         [self.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];  
  37.           
  38.           
  39.         [self.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:@"text/plain",@"application/json",@"text/json",@"text/javascript",@"text/html", nil nil]];  
  40.           
  41.      
  42.       
  43.     return self;  
  44.  


[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef NS_ENUM(NSUInteger,HTTPSRequestType)  
  2.  
  3.     HTTPSRequestTypeGet 0,  
  4.     HTTPSRequestTypePost  
  5. };  
  6.   
  7. typedef void(^completeBlock)( NSDictionary *_Nullable object,NSError _Nullable error);  
  8.   
  9. @interface BJHTTPSession NSObject  
  10.   
  11. (nullable NSURLSessionDataTask *)GET:(nonnull NSString *)urlString  
  12.                              paraments:(nullable id)paraments  
  13.                          completeBlock:(nullable completeBlock)completeBlock;  
  14.   
  15. (nullable NSURLSessionDataTask *)POST:(nonnull NSString *)urlString  
  16.                               paraments:(nullable id)paraments  
  17.                           completeBlock:(nullable completeBlock)completeBlock;  
  18.   
  19. (nullable NSURLSessionDataTask *)requestWithRequestType:(HTTPSRequestType)type  
  20.                                                 urlString:(nonnull NSString *)urlString  
  21.                                                 paraments:(nullable id)paraments  
  22.                                             completeBlock:(nullable completeBlock)completeBlock;  
  23.   
  24. (void)AFNetworkStatus;  
  25.   
  26.   
  27.   
  28.   
  29. @end  


[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //  
  2. //  BJHTTPSession.m  
  3. //  VRMax  
  4. //  
  5. //  Created by VRGATE on 16/5/12.  
  6. //  Copyright © 2016年 AngieMita. All rights reserved.  
  7. //  
  8.   
  9. #import "BJHTTPSession.h"  
  10. #import "BJAppClient.h"  
  11. #import   
  12. #import   
  13. #import   
  14. #import "UIImage+compressIMG.h"  
  15.   
  16. @implementation BJHTTPSession  
  17.   
  18. (nullable NSURLSessionDataTask *)GET:(nonnull NSString *)urlString  
  19.                              paraments:(nullable id)paraments  
  20.                          completeBlock:(nullable completeBlock)completeBlock  
  21.  
  22.     return [[BJAppClient sharedClient] GET:urlString  
  23.                                 parameters:paraments  
  24.                                   progress:^(NSProgress _Nonnull downloadProgress)  
  25.                                   success:^(NSURLSessionDataTask _Nonnull task, id  _Nullable responseObject)  
  26.                                       completeBlock(responseObject,nil);  
  27.                                   failure:^(NSURLSessionDataTask _Nullable task, NSError _Nonnull error)  
  28.                                       completeBlock(nil,error);  
  29.                                   }];  
  30.  
  31.   
  32. (nullable NSURLSessionDataTask *)POST:(nonnull NSString *)urlString  
  33.                               paraments:(nullable id)paraments  
  34.                           completeBlock:(nullable completeBlock)completeBlock  
  35.  
  36.     // 不加上这句话,会报“Request failed: unacceptable content-type: text/plain”错误  
  37.   
  38.     [BJAppClient sharedClient].requestSerializer [AFJSONRequestSerializer serializer];//请求  
  39.     [BJAppClient sharedClient].responseSerializer [AFHTTPResponseSerializer serializer];//响应  
  40.       
  41.     // post请求  
  42.     return [[BJAppClient sharedClient] POST:urlString  
  43.                                  parameters:paraments  
  44.                   constructingBodyWithBlock:^(id  _Nonnull formData)  
  45.                       // 拼接data到请求体,这个block的参数是遵守AFMultipartFormData协议的。  
  46.                   progress:^(NSProgress _Nonnull uploadProgress){  
  47.                   success:^(NSURLSessionDataTask _Nonnull task, id  _Nullable responseObject)  
  48.                       NSLog(@"%@", responseObject);  
  49.                       NSDictionary *dict [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];  
  50.                       NSLog(@"dict start ----\n%@   \n ---- end  -- ", dict);  
  51.                       // 请求成功,解析数据  
  52.                       completeBlock(responseObject,nil);  
  53.                   failure:^(NSURLSessionDataTask _Nullable task, NSError _Nonnull error)  
  54.                       NSLog(@"%@", [error localizedDescription]);  
  55.                       // 请求失败  
  56.                       completeBlock(nil,error);  
  57.                   }];  
  58.  
  59.   
  60. #pragma mark 简化  
  61. (nullable NSURLSessionDataTask *)requestWithRequestType:(HTTPSRequestType)type  
  62.                                                 urlString:(nonnull NSString *)urlString  
  63.                                                 paraments:(nullable id)paraments  
  64.                                             completeBlock:(nullable completeBlock)completeBlock  
  65.  
  66.     switch (type)  
  67.         case HTTPSRequestTypeGet:  
  68.          
  69.             return  [BJHTTPSession GET:urlString  
  70.                              paraments:paraments  
  71.                          completeBlock:^(NSDictionary _Nullable object, NSError _Nullable error)  
  72.                              completeBlock(object,error);  
  73.                          }];  
  74.          
  75.         case HTTPSRequestTypePost:  
  76.             return [BJHTTPSession POST:urlString  
  77.                              paraments:paraments  
  78.                          completeBlock:^(NSDictionary _Nullable object, NSError _Nullable error)  
  79.                              completeBlock(object,error);  
  80.                          }];  
  81.      
  82.       
  83.  
  84.   
  85. #pragma mark  取消所有的网络请求  
  86.   
  87.   
  88.   
  89. +(void)cancelAllRequest  
  90.  
  91.     [[BJAppClient sharedClient].operationQueue cancelAllOperations];  
  92.  
  93.   
  94.   
  95.   
  96. #pragma mark   取消指定的url请求/  
  97.   
  98.   
  99. +(void)cancelHttpRequestWithRequestType:(NSString *)requestType  
  100.                        requestUrlString:(NSString *)string  
  101.  
  102.     NSError error;  
  103.       
  104.     NSString urlToPeCanced [[[[BJAppClient sharedClient].requestSerializer  
  105.                                   requestWithMethod:requestType URLString:string parameters:nil error:&error] URL] path];  
  106.       
  107.     for (NSOperation operation in [BJAppClient sharedClient].operationQueue.operations)  
  108.         //如果是请求队列  
  109.         if ([operation isKindOfClass:[NSURLSessionTask class]])  
  110.             //请求的类型匹配  
  111.             BOOL hasMatchRequestType [requestType isEqualToString:[[(NSURLSessionTask *)operation currentRequest] HTTPMethod]];  
  112.             //请求的url匹配  
  113.             BOOL hasMatchRequestUrlString [urlToPeCanced isEqualToString:[[[(NSURLSessionTask *)operation currentRequest] URL] path]];  
  114.             //两项都匹配的话  取消该请求  
  115.             if (hasMatchRequestType&&hasMatchRequestUrlString 
  116.                 [operation cancel];  
  117.              
  118.          
  119.      
  120.  
  121.   
  122. (void)AFNetworkStatus  
  123.  
  124.       
  125.     //1.创建网络监测者  
  126.     AFNetworkReachabilityManager *manager [AFNetworkReachabilityManager sharedManager];  
  127.       
  128.       
  129.       
  130.     [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)  
  131.         //这里是监测到网络改变的block  可以写成switch方便  
  132.         //在里面可以随便写事件  
  133.         switch (status)  
  134.             case AFNetworkReachabilityStatusUnknown:  
  135.                 NSLog(@"未知网络状态");  
  136.                 break;  
  137.             case AFNetworkReachabilityStatusNotReachable:  
  138.                 NSLog(@"无网络");  
  139.                 networkReachabilityStatusUnknown();  
  140.                 break;  
  141.                   
  142.             case AFNetworkReachabilityStatusReachableViaWWAN:  
  143.                 NSLog(@"蜂窝数据网");  
  144.                 networkReachabilityStatusReachableViaWWAN();  
  145.                 break;  
  146.                   
  147.             case AFNetworkReachabilityStatusReachableViaWiFi:  
  148.                 NSLog(@"WiFi网络");  
  149.                   
  150.                 break;  
  151.                   
  152.             default:  
  153.                 break;  
  154.          
  155.           
  156.     }]  
  157.  
  158.   
  159. void networkReachabilityStatusUnknown()  
  160.  
  161.     UIAlertController *alert [UIAlertController alertControllerWithTitle:@"已为”VRMAX“关闭蜂窝移动数据"  
  162.                                                                    message:@"您可以在”设置“中为此应用程序打开蜂窝移动数据。"  
  163.                                                             preferredStyle:UIAlertControllerStyleAlert];  
  164.     [alert addAction:[UIAlertAction actionWithTitle:@"设置"  
  165.                                               style:UIAlertActionStyleDefaul 
  166.                                             handler:^(UIAlertAction _Nonnull action)  
  167.                                                 canOpenURLString(@"prefs:root=MOBILE_DATA_SETTINGS_ID");  
  168.                                             }]];  
  169.     [alert addAction:[UIAlertAction actionWithTitle:@"好"  
  170.                                               style:UIAlertActionStyleCancel handler:nil]];  
  171.  
  172.   
  173. void networkReachabilityStatusReachableViaWWAN()  
  174.  
  175.     UIAlertController *alert [UIAlertController alertControllerWithTitle:@"“VRMAX”正在使用流量,确定要如此土豪吗?"  
  176.                                                                    message:@"建议开启WIFI后观看视频。"  
  177.                                                             preferredStyle:UIAlertControllerStyleAlert];  
  178.     [alert addAction:[UIAlertAction actionWithTitle:@"设置"  
  179.                                               style:UIAlertActionStyleDefaul 
  180.                                             handler:^(UIAlertAction _Nonnull action)  
  181.                                                 canOpenURLString(@"prefs:root=MOBILE_DATA_SETTINGS_ID");  
  182.                                             }]];  
  183.     [alert addAction:[UIAlertAction actionWithTitle:@"好"  
  184.                                               style:UIAlertActionStyleCancel handler:nil]];  
  185.  
  186. @end
<think>我们正在寻找替代大量使用` `来实现文本对齐的优雅方法。根据引用[1][2][3]的内容,过度使用` `可能导致布局问题,尤其是在响应式设计中。引用[4]提到了使用Flexbox布局的`align-content`属性,但这里我们更关注水平对齐问题。 优雅的替代方案: 1. 使用CSS的Flexbox布局:可以轻松实现元素的对齐,无需使用` `。 2. 使用CSS Grid布局:同样可以精确控制元素位置。 3. 使用text-align属性:对于文本对齐,使用text-align更合适。 4. 使用margin和padding:通过调整间距实现对齐。 5. 使用伪元素:在某些情况下,可以用伪元素来添加间隔。 具体到问题中的代码,原代码中使用了多个` `来分隔指令ID、类型和按钮。我们可以通过CSS布局来重构,避免使用` `。 重构步骤: 1. 将指令信息(ID和类型)和操作按钮(暂停、删除)分别放入两个容器中。 2. 使用Flexbox布局,让这两个容器分别占据左右两侧。 3. 在左侧信息容器内,也可以使用Flex布局来设置ID和类型的间距。 代码示例: 原代码结构(简化): ```html <div class="instruction-info"> <span class="cmd-id"> {{ cmd.id }}</span>         <span class="cmd-type">{{ cmd.type }}</span>        <el-button ...>暂停</el-button> <el-button ...>删除</el-button> </div> ``` 重构后: ```html <div class="instruction-info"> <div class="info-left"> <span class="cmd-id">{{ cmd.id }}</span> <span class="cmd-type">{{ cmd.type }}</span> </div> <div class="info-right"> <el-button ...>暂停</el-button> <el-button ...>删除</el-button> </div> </div> ``` 样式: ```css .instruction-info { display: flex; justify-content: space-between; /* 左右两侧分开 */ align-items: center; /* 垂直居中 */ } .info-left { display: flex; gap: 20px; /* 使用gap属性设置子元素之间的间距 */ } .info-right { display: flex; gap: 10px; /* 按钮之间的间距 */ } ``` 这样,我们完全移除了` `,使用Flex布局的gap属性(或者margin)来控制间距,更加清晰和易于维护。 另外,根据引用[3]提到的,在表格对齐等场景中,如果确实需要空格,可以考虑使用` `作为占位,但布局场景中应优先使用CSS。 总结:使用CSS布局技术(Flexbox或Grid)替代` `进行对齐是更优雅、更可维护的方式。 相关问题: 1. 在响应式设计中,如何调整Flexbox布局以适应不同屏幕尺寸? 2. 除了Flexbox,CSS Grid在实现复杂布局时有哪些优势? 3. 如何解决Flexbox布局中的浏览器兼容性问题? 4. 在文本排版中,如何实现首行缩进、段落间距等效果而不使用` `或` `?</think># 优雅的文本对齐方案:替代大量 的CSS布局方法 在HTML中使用大量` `来实现对齐不仅代码臃肿,还会导致维护困难和响应式问题。下面我将介绍几种更优雅的CSS替代方案。 ## 问题分析 使用` `的常见问题: - 代码可读性差,难以维护 - 无法适应不同屏幕尺寸 - 间距控制不精确 - 不利于响应式设计 ## 优雅的CSS替代方案 ### 1. Flexbox布局(推荐) ```html <div class="flex-container"> <div class="label">指令ID:</div> <div class="value">CMD-2023-001</div> <div class="label">类型:</div> <div class="value">类型A</div> <div class="actions"> <button>暂停</button> <button>删除</button> </div> </div> <style> .flex-container { display: flex; align-items: center; /* 垂直居中 */ gap: 15px; /* 元素间距 */ } .label { font-weight: bold; min-width: 70px; /* 固定标签宽度 */ } .actions { margin-left: auto; /* 自动将按钮推到右侧 */ display: flex; gap: 10px; } </style> ``` ### 2. Grid布局(复杂布局首选) ```html <div class="grid-container"> <div class="label">指令ID:</div> <div class="value">CMD-2023-001</div> <div class="label">类型:</div> <div class="value">类型A</div> <div class="actions"> <button>暂停</button> <button>删除</button> </div> </div> <style> .grid-container { display: grid; grid-template-columns: auto 1fr auto 1fr auto; /* 5列布局 */ align-items: center; gap: 15px; } .actions { grid-column: 5; /* 将按钮放在最后一列 */ display: flex; justify-content: flex-end; /* 右对齐 */ gap: 10px; } </style> ``` ### 3. 伪元素实现等宽间距 ```html <div class="spaced-container"> <span>指令ID: CMD-2023-001</span> <span>类型: 类型A</span> <div class="actions"> <button>暂停</button> <button>删除</button> </div> </div> <style> .spaced-container { display: flex; } .spaced-container > span:not(:last-child)::after { content: ""; display: inline-block; width: 30px; /* 自定义间距 */ } </style> ``` ### 4. 文本对齐与间距控制 ```css /* 替代   的文本对齐方案 */ .text-align-center { text-align: center; } .text-align-right { text-align: right; } /* 替代   的间距控制 */ .spacing-small { margin-right: 8px; } .spacing-medium { margin-right: 16px; } .spacing-large { margin-right: 24px; } ``` ## 实际应用示例 ```html <div class="command-card"> <div class="command-header"> <h3>任务标题</h3> </div> <div class="command-grid"> <div class="command-info"> <span class="label">指令ID:</span> <span class="value">CMD-2023-001</span> </div> <div class="command-info"> <span class="label">类型:</span> <span class="value">类型A</span> </div> <div class="command-actions"> <button class="btn-warning">暂停</button> <button class="btn-danger">删除</button> </div> </div> </div> <style> .command-card { border: 1px solid #e0e0e0; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); } .command-header { margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; } .command-grid { display: grid; grid-template-columns: 1fr 1fr auto; gap: 15px; align-items: center; } .command-info { display: flex; gap: 10px; } .label { font-weight: bold; min-width: 60px; } .command-actions { display: flex; justify-content: flex-end; gap: 10px; } .btn-warning { background: #ffc107; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; } .btn-danger { background: #dc3545; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; } </style> ``` ## 最佳实践建议 1. **优先使用Flexbox/Grid布局**:现代CSS布局技术提供了更强大的对齐能力[^4] 2. **使用gap属性控制间距**:替代` `创建元素间距 3. **利用margin/padding进行微调**:精确控制元素间距 4. **避免使用固定宽度**:使用min-width/max-width实现响应式设计 5. **使用CSS变量统一间距**: ```css :root { --spacing-sm: 8px; --spacing-md: 16px; --spacing-lg: 24px; } .element { margin-right: var(--spacing-md); } ``` 6. **在必须使用空格时**:考虑使用` `(1/6em)或` `(1/2em)替代` `[^2][^3] 通过这些CSS技术,您可以完全避免使用` `进行布局控制,创建更干净、更可维护且响应式的设计。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值