常见问题汇总
AFNetworking Get请求失败
- 今天第一次使用AFNetworking,发现NSURLSessionDataTask一直报错,错误信息:
- Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text\/html"
- 经过一番网上排查,网上有人说是AF2.0本身的问题,解析格式不全,所以需要在AF的源文件AFURLResponseSerialization.m中修改代码就能解决,修改文件228行处
self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil nil];
改为
self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil nil];
- 即可,试过确实可以,但AF还在持续更新的类库,不宜随意修改,特别是在用了CocoaPods之后,如果之后更新库,此类错误又会重复出现,随后在另外一篇文章中发现acceptableContentTypes是一个开放的属性,既然这样,就证明acceptableContentTypes可以在外部被修改,所以可以在
初始化HttpClient单利的时候改变这一值:
- (instancetype)initWithBaseURL:(NSURL *)url {
if (self = [super initWithBaseURL:url]) {
self.responseSerializer = [AFJSONResponseSerializer serializer];
self.requestSerializer.timeoutInterval = TimeoutInterval;
self.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil nil];
[self setHTTPHeader]; // 可在此处设置Http头信息
}
return self;
}
项目中集成Alipay支付宝接口
首先下载支付钱包接口Demo源代码,导入如下内容:
- openssl 文件夹下的所有文件
- Util 文件夹的所有文件
- libcrypto.a
- libssl.a
- AlipaySDK.bundle
- AlipaySDK.framework
将上面所有文件加入项目后,在项目的Build Settings→Search Paths中指定Framework Search Path、Header Search Paths和Library Search Paths为导入的文件位置,如:$(PROJECT_DIR)\/JZ-KongGe\/AliPay
Xcode7 真机运行时报错
出现场景
- 正常调试是没有问题的,但是在Archive的时候,报出了这个错误。
错误信息
ld: 'XXX' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)问题分析
- 从上述的错误中应该可以看出,这是因为一个第三方的库不兼容,我的工程中开启了 ENABLE_BITCODE (Xcode7.0默认是开启Enable Bitcode的),而这个第三方的库在编译的时候没有 enable bitcode,如果你导入的一些第三方库在编译的时候没有Enable Bitcode 的话,就会导致上诉问题。
解决方法
- 方法一:使用Enable Bitcode的第三方库
- 方法二:将工程中的Enable Bitcode设置为NO

IOS 获取定位权限
配置信息
- 在plist文件中添加NSLocationWhenInUseUsageDescription 和 NSLocationAlwaysUsageDescription 这两项;
- Type选择Boolean,Value均为YES。
代码部分
- 首先,我们需要在工程中导入CoreLocation系统框架。然后在我们的控制器中引入头文件。
#import <CoreLoction/CoreLocation.h>- 然后,声明一个CLLocationManager对象作为成员变量,用于定位获取经纬度坐标,并遵守协议CLLocationManager的协议。
@interface TYViewController () <CLLocationManagerDelegate> { CLLocationManager *_locationManager; }- 实现其中的代理方法
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { //将经度显示到label上 self.longitude.text = [NSString stringWithFormat:@"%lf", newLocation.coordinate.longitude]; //将纬度现实到label上 self.latitude.text = [NSString stringWithFormat:@"%lf", newLocation.coordinate.latitude]; // 获取当前所在的城市名 CLGeocoder *geocoder = [[CLGeocoder alloc] init]; //根据经纬度反向地理编译出地址信息 [geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *array, NSError *error){ if (array.count > 0){ CLPlacemark *placemark = [array objectAtIndex:0]; //将获得的所有信息显示到label上 self.location.text = placemark.name; //获取城市 NSString *city = placemark.locality; if (!city) { //四大直辖市的城市信息无法通过locality获得,只能通过获取省份的方法来获得(如果city为空,则可知为直辖市) city = placemark.administrativeArea; } NSLog(@"city = %@", city); _cityLable.text = city; [_cityButton setTitle:city forState:UIControlStateNormal]; } else if (error == nil && [array count] == 0){ NSLog(@"No results were returned."); } else if (error != nil){ NSLog(@"An error occurred = %@", error); } }]; //系统会一直更新数据,直到选择停止更新,因为我们只需要获得一次经纬度即可,所以获取之后就停止更新 [manager stopUpdatingLocation]; }- 最后在viewDidLoad中初始化定位管理器。
- (void)viewDidLoad { [super viewDidLoad]; [self initializeLocationService]; // Do any additional setup after loading the view. } - (void)initializeLocationService { // 初始化定位管理器 _locationManager = [[CLLocationManager alloc] init]; // 设置代理 _locationManager.delegate = self; // 设置定位精确度到米 _locationManager.desiredAccuracy = kCLLocationAccuracyBest; // 设置过滤器为无 _locationManager.distanceFilter = kCLDistanceFilterNone; // 开始定位 [_locationManager startUpdatingLocation]; }
接下来编译并运行程序,手动在iOS模拟器上配置定位坐标,即可打印出该经纬度坐标对应的城市名(真机可直接打印出当前城市名)。
CLPlacemark类中封装了很多的地理信息属性,包括完整的地址(大到国家,小到街道)和地理名称等等,可以酌情使用。
PS:如果定位出的街道信息为英文,那请先处理本地化,同时模拟器调整语言为中文。
iOS中添加UITapGestureRecognizer手势识别后,UITableView的didSelectRowAtIndexPath失效
用TableView写了一个登陆界面,帐号和密码两个Cell中加入了TextField。由于想在TableView的空白处点击时收起键盘,所以他注册了一个UITapGestureRecognizer来识别手势。
ViewDidLoad中注册手势的部分代码如下:
UITapGestureRecognizer *oneTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyBoard)] autorelease];
oneTap.delegate = self;
oneTap.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:oneTap];
其中hideKeyBoard方法就省略了,基本就是几个resignFirstResponder。 然后发生了一个奇怪的现象,点击“找回密码”那一栏时没有反应了!!!
调试后我发现委托方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath不执行了。
目测原因是UITapGestureRecognizer截获了touch事件,导致didSelectRowAtIndexPath方法无法响应。
查阅了相关文档后找到了一种可行的解决方法:重写UIGestureRecognizerDelegate中的
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch方法。
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// 输出点击的view的类名
NSLog(@"%@", NSStringFromClass([touch.view class]));
// 若为UITableViewCellContentView(即点击了tableViewCell),则不截获Touch事件
if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}
再次调试,这回didSelectRowAtIndexPath响应了,解决UITapGestureRecognizer手势截获Touch事件的问题!
PS:笔者对Tap手势外其他手势进行了测试,Pinch、Pan、Swipe、Rotation没有产生类似的问题,而Tap和LongPress产生了这样的问题。多谢Doralink提醒,写技术博客还是要写的全面一些。
Code=3000 "未找到应用程序的“aps-environment”的授权字符串" 解决办法
这个问题可能比较多出现,网上呢一股脑的方案是:描述文件,推送证书与项目中的bundle identifer 不一致,或者什么appid不一致呀,什么证书生成顺序不一致呀,什么xcode的code signing没有配置呀,就不写了,网上搜很多,我现在就把自己的问题说一下:
出现的背景是:原先的项目兼容iOS10,远程推送也用了最新的iOS10的推送框架,创建证书、描述文件的时候的appid,顺序啊,bundle identifer呀都正常
如果大家谁也出现这个问题了,不要忘记去看看xcode中的一个设置:
就是上图,记得看看打开没打开这个‘Push Notification’开关,打开之后,steps这两步骤会自动检查APP ID等推送文件的合法性。我的项目打开这个开关之后,验证也通过了,再运行,不会出现一开始‘Code=3000 “未找到应用程序的“aps-environment”的授权字符串”’的错误。
如果这两个step报错,就要去按照网上其他的重新设置provisioning profile,bundle identifer等,让其保持一致性。