最近写简书不多,GET请求也可以将参数放在字典

2019-09-11 作者:编程   |   浏览(68)

未增添遮掩物效果:

由此后边学习的HTTP合同的基本知识,GET/POST央求的差距,NSUTiguanLConnection 和 NSU牧马人LSession的应用,已经主导领悟了网络要求的艺术,可是相对使用相比麻烦,AFNetworking是对NSUENVISIONLConnection 和 NSU揽胜极光LSession的包装,使互联网须求尤其简便易行轻巧,是一款非常低价的第三方框架。AFNetworking3.0今后移除了对NSU君越LConnection的支撑。看一下AFNetworking 历史版本 以及框架

开篇

图片 1喵神镇楼.jpg

方今写简书非常的少,除了近期一篇匆匆的FFMPEG的说历史学习为主没写多少,主如若目前比较忙,又是硬件设施的调护医治,又是新要求的加入,前几天就来写一下类型中的一个文化,闲话少叙直入正题吧。

图片 2iPhone_6_-_iPhone_6___iOS_9_3__13E230_.png

iOS 的webView分为两类, 一类是 UIKit框架下的 UIWebView , 另一类是 WebKit框架下的 WKWebView. UIWebView 与JS 的互相是依附于JavaScriptCore,而WKWebView则是iOS8.0公布的.so 要是项目不供给包容iOS8.0以下的版本则采纳WKWebView就能够.本文将介绍UIWebView WKWebView 与JS的交互.

图片 3WechatIMG2.png

图片 4AFNetworking版本更新图片 5AFNetworking框架

百度地图的施用

百度地图API的导入网络说了大多坑,不过本人蒙受的比比较少,这里就放八个比较宽泛的呢。坑一:

图片 6奥联WIFI_xcodeproj.png

如上海体育场地所示,在infoplist里出席那个字段,并且这里还能安装提醒的开始和结果。不加的话,嘿嘿嘿,期待您的品尝。坑二:如下图

图片 7Pasted_Graphic_jpg.png导入百度地图API运转之后报上海体育场面错误大概18到二十个左右,消除办法增添libstdc .6.0.9 的库。填完坑之后看一下大家明日要亲自过问的功力啊。图片 8渠道规划图.gif

那边达成的剧情正是在定点到的眼下都市内的路子设计,达成驾乘,公共交通,步行三种设计方式。

对于UIWebView大家都不目生,网页或富文本加载都能用到,这里对于UIWebView基本的用法就不开展介绍了.UIWebView与JS的并行方面重纵然依赖于JavaScriptCore类库,上边简单的介绍下那些类库.<JavaScriptCore/JavaScriptCore.h> Command 左键 步入

加上掩饰物后效果:

那几个在GitHub上都足以观察,能够去GitHub上查看。

在意要点:
  • 这里大家运用的是地点到地点之间的不二秘技设计,所以大家在查询的经过中必然要设置查询的都会,不然无法查找成功(当然也足以用经纬度的章程,那就另说了)。

  • 办法切换难题,要是我们想要像上海体育地方所示的不相同渠道设计间的切换,大家要留神的正是地图上业已存在的门径轨迹和标明的排除难点。

  • 作者们在不一致规格下统一筹算路径要留意他们是见仁见智的查询艺术,以及她们不等的情商方式,这些大家能够具体点进百度地图静态库的方法去查看。

是因为在档案的次序中,并未整理出来,这里大家就贴一些尤为重要的代码。因为二种门路设计其实原理一致这里大家以驾乘的路子设计做三个事例。因为要顾及到此前是还是不是有轨道和标记由此我们要先做扫除管理,代码如下

 [_mapView removeOverlays:_mapView.overlays]; NSArray *annArray = [[NSArray alloc]initWithArray:_mapView.annotations]; [_mapView removeAnnotations: annArray];

自此我们创造路线设计的点子

 _searcher = [[BMKRouteSearch alloc]init]; _searcher.delegate = self; //发起检索 BMKPlanNode* start = [[BMKPlanNode alloc]init] ; start.name = _startFiled.text; BMKPlanNode* end = [[BMKPlanNode alloc]init]; end.name = _endFiled.text; start.cityName = self.city; end.cityName = self.city; BMKDrivingRoutePlanOption *driveRouteSearchOption =[[BMKDrivingRoutePlanOption alloc]init]; driveRouteSearchOption.from = start; driveRouteSearchOption.to = end;

此处要注意的就是因为我们是驾车路线设计,所以成立的是BMKDrivingRoutePlanOption,我们进来到内部方法能够观望,入过大家是公共交通和徒步对应的则是他们分其余Option,发起检索成功后会调取他的磋商形式,这里的前提是要遵从BMKRouteSearchDelegate左券

- onGetDrivingRouteResult:(BMKRouteSearch*)searcher result:(BMKDrivingRouteResult*)result errorCode:(BMKSearchErrorCode)error

在上述的合计章程中,大家设置起源,终点,以及路段入口新闻和各轨迹点的总和

 for (int i = 0; i < size; i  ) { BMKDrivingStep *tansitStep = [plan.steps objectAtIndex:i]; if  { BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init]; annotation.coordinate = plan.terminal.location; annotation.title = @"起点"; [_mapView addAnnotation:annotation]; } else if (i == size - 1) { BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init]; annotation.coordinate = plan.terminal.location; annotation.title = @"终点"; [_mapView addAnnotation:annotation]; } BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init]; annotation.coordinate = tansitStep.entrace.location; //路段入口信息 annotation.title = tansitStep.instruction; //路程换成说明 [_mapView addAnnotation:annotation]; //轨迹点总数累计 planPointCounts  = tansitStep.pointsCount; } //轨迹点 BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts]; //文件后缀名改为mm int i = 0; for (int j = 0; j < size; j  ) { BMKTransitStep *transitStep = [plan.steps objectAtIndex:j]; int k = 0; for (k = 0; k < transitStep.pointsCount; k  ) { temppoints[i].x = transitStep.points[k].x; temppoints[i].y = transitStep.points[k].y; i  ; } } //通过points构建BMKPolyline BMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts]; [_mapView addOverlay:polyLine]; //添加路线overlay delete []temppoints; [self mapViewFitPolyLine:polyLine];

像这种类型大家就到位了门道设计的重大安装。

百度地图提供了详实的POI检索,如下图大家设置八个分界面接纳大家想要检索的剧情,然后依照我们挑选的内容去在地形图上标志处各样对应的点,并呈现出她的详细消息。然后大家点击具体的cell,然后大家依据模型中的数据地点也许经纬度,可以设计处我们所在地到目标地的路径设计,一样有开车,公共交通,步行,三种。这里只可以嘲弄一下为什么那么多电话都不曾嘞。

图片 9IMG_0003.PNG图片 10IMG_0004.PNG

小编们要进行POI检索,首先要遵守BMKPoiSearchDelegate合同,然后进行寻觅

 _searcher2 =[[BMKPoiSearch alloc]init]; _searcher2.delegate = self; //发起检索 BMKNearbySearchOption *option = [[BMKNearbySearchOption alloc]init]; option.pageIndex = 1; //当前索引页 option.pageCapacity = 10; //分页量 option.location = CLLocationCoordinate2DMake(self.lat2, self.lon2); option.keyword = self.str; option.radius = 3000; BOOL flag = [_searcher2 poiSearchNearBy:option]; if { NSLog(@"周边检索发送成功"); } else { NSLog(@"周边检索发送失败"); }

寻觅成功后会走到和煦格局

- onGetPoiResult:(BMKPoiSearch*)searcher result:(BMKPoiResult*)poiResultList errorCode:(BMKSearchErrorCode)error

在这里我们收获了含有详细音讯的一个数组,然后我们抽出BMKPoiInfo对象中的uid,去开展详尽检索,相同的时间并把它转换为一个model,去创建大家的tableview,然后把收获的应和数据展现到下半部的列表中,在点击tableview的详尽事件中张开传值,完成路线的准备。model中的部分属性如下:

@interface GSMapModel : NSObject///POI名称@property (nonatomic, strong) NSString* name;///POIuid@property (nonatomic, strong) NSString* uid;///POI地址@property (nonatomic, strong) NSString* address;///POI所在城市@property (nonatomic, strong) NSString* city;///POI电话号码@property (nonatomic, strong) NSString* phone;///POI邮编@property (nonatomic, strong) NSString* postcode;

端详检索对应的说道章程

//搜索的详细结果- onGetPoiDetailResult:(BMKPoiSearch*)searcher result:(BMKPoiDetailResult*)poiDetailResult errorCode:(BMKSearchErrorCode)errorCode{ if (errorCode == BMK_SEARCH_NO_ERROR) { //在此处理正常结果 } else if (errorCode == BMK_SEARCH_AMBIGUOUS_KEYWORD){ //当在设置城市未找到结果,但在其他城市找到结果时,回调建议检索城市列表 // result.cityList; NSLog(@"起始点有歧义"); } else { NSLog(@"抱歉,未找到结果"); }

作者们想要本身定义我们想要看到的大头针模样,将在对他进行自定义。上面介绍一种轻巧的管理大头针样式的诀窍,如若想要具体的依照差异的状态来进行自定义,将在开展剖断,依照他们分裂的情景去给定相应的标号图片

- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation{ BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"]; newAnnotationView.pinColor = BMKPinAnnotationColorPurple; newAnnotationView.animatesDrop = NO;// 设置该标注点动画显示 newAnnotationView.annotation=annotation; newAnnotationView.image = [UIImage imageNamed:@"mapicon"]; //把大头针换成别的图片 newAnnotationView.size = CGSizeMake; return newAnnotationView;}

图片 11JavaScriptCore的类和左券.png

图片 12WechatIMG3.png

 AFHTTPSessionManager *manager =[AFHTTPSessionManager manager]; NSDictionary *dict = @{ @"username":@"520it", @"pwd":@"520it" }; // parameters 参数字典 [manager GET:@"http://120.25.226.186:32812/login" parameters:dict progress:^(NSProgress * _Nonnull downloadProgress) { //进度 //进度 } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // task 我们可以通过task拿到响应头 // responseObject:请求成功返回的响应结果(AFN内部已经把响应体转换为OC对象,通常是字典或数组) } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { // error 错误信息 }];

 AFHTTPSessionManager *manager =[AFHTTPSessionManager manager]; NSDictionary *dict = @{ @"username":@"520it", @"pwd":@"520it" }; [manager POST:@"http://120.25.226.186:32812/login" parameters:dict progress:^(NSProgress * _Nonnull downloadProgress) { // 进度 } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // 请求成功 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { // 请求失败 }];

后记

地图中大家用的相当多的正是长久,POI检索和路径设计了,定位的话,相信不管是合法SDK照旧英特网种种材质都够详细的了,作者就不再重复了,这里根本对路径设计和POI检索做出表达,希望对大家有所扶助。

  1. JSContext 为JavaScript提供运转情形
  2. JSValue 是JavaScript和Object-C之间沟通的大桥
  3. JSManagedValue 为开拓人士提供对象内部存款和储蓄器管理
  4. JSVirtualMachine 为JavaScript的运维提供了尾部财富
  5. JSExport 作为JavaScript和Objective-C二种语言的互通合同。

MKMapView上增加图片掩盖物的原理和增多轨道的原理基本一样(轨迹可参看上一篇文章),都急需自定义图层(实现MKOverlay合同)和渲染器(继承MKOverlayRenderer)。

在意:我们开采GET和POST央浼如出一辙,仅仅换了八个名字,GET要求也足以将参数放在字典中,也能够将参数拼接在url之后parameters传nil。别的没有供给敞开Task,因为AFN内部已经帮大家展开了别的:AFN暗中认可会把服务器再次回到给大家的数目作为是JSNO数据,而且AFN内部已经把响应体JSON数据调换为OC对象,常常是字典或数组。那么一旦服务器重回的XML呢?那时我们须要团结设置AFN解析格局

补给内容

今天有年轻人伴问看了小说想清楚百度地图的模糊搜索是如何是好的,输入地名就能够自动联想好狠心的模范,这里就补给一下呢,其实也是POI寻找的一有的,是城市内搜寻遵照输入的地名发起搜索,然后把寻觅内容展现到tableview上罢了。如下图:

图片 13模糊寻觅.gif

当大家转移输入框的开始和结果时其实里面包车型的士操作是何等吗,上面大家一小点介绍一下他。这里我们要做的是POI检索,由此首先要遵从BMKPoiSearchDelegate合同,创立搜索的代码如下:

 _poisearcher = [[BMKPoiSearch alloc]init]; _poisearcher.delegate = self; BMKCitySearchOption *citySearchOption = [[BMKCitySearchOption alloc]init]; citySearchOption.pageIndex = 0; citySearchOption.pageCapacity = 20; citySearchOption.city= self.city; citySearchOption.keyword = _inputFiled.text;

成功现在会走上边那么些公约情势

-onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult *)poiResult errorCode:(BMKSearchErrorCode)errorCode

此间大家就收获了归来的内容,然后把它里面的数据取到转变为模型呈现到tableview上就好了,可是,为何是只是呢,因为您那样做并不能够赢得想要的结果,因为你那边做的找寻只是二回的,并无法落到实处每变动二个字就重新搜索显示出位置,我们要对输入框做处理

 [_inputFiled addTarget:self action:@selector(inputaction:) forControlEvents:UIControlEventEditingChanged];

增进风浪,完成对输入框变化的监听,然后完结方式。

#pragma mark - 输入框的实时监听-inputaction:(UITextField *)textField{ [self performSelector:@selector withObject:self afterDelay:0.5];}

这里大家监听输入框的变迁,然后把相应的查找写到delay方法中就能够了。那样就落实了多少的显示,然后点击相应的cell的时候,把数据传给上个分界面接Ok了啊,这里为了客户体验大家能够监听tableview的滚动,当滚动的时候让输入框的键盘消失,代码如下:

#pragma mark -滚动隐藏键盘-scrollViewDidScroll:(UIScrollView *)scrollView{ [self.view endEditing:YES];}

如此那般大家就落到实处了歪曲搜索了,是还是不是依旧比较轻便的。有其他难点之后再跟着补充吧。

在UIWebView中,native与JS的相互其实就是经过拦截request的必经之路完毕的. 主要有三种格局, 左券 和 Blcok.

CustomOverlay.h实现:

manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
协议

JSExport中从未预订任何的主意,连可选的(@optional)都并未有,不过富有继续了该左券(@protocol)的商谈(注意不是Objective-C的类(@interface))中定义的措施,都得以在JSContext中被利用。JSExport商业事务详细讲授

Native中的代码

/** * 制定协议(遵循 JSExport协议) */@protocol JSObjcProtocol <JSExport>/** * 商品详情页面返回按钮 */- goBack;/** * 购物车界面编辑按钮 */- edit;/** * 支付订单界面确认支付按钮 以及三种传值方式 *///javascript:App.pay;- pay:(NSString *)payInfo;//App.payInfoUserIDWithUserName("用户ID","用户名字");- payInfoUserID:(NSString *)userid withUserName:(NSString *)userName;//App.payInfoOrder("订单号","支付方式");JSExportAs(payInfoOrder, - payInfoOrder:(NSString *)order withPayType:(NSString *)type);@nd

//控制器遵守协议之后, 协议中的方法都需要实现.@interface UIWebViewController ()<UIWebViewDelegate,JSObjcProtocol>@property (strong, nonatomic) IBOutlet UIWebView *webView;//为JavaScript提供运行环境@property (strong ,nonatomic) JSContext *jsContext;@end

- webViewDidFinishLoad:(UIWebView *)webView{ //获取当前加载完成网页的上下文环境 self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //将设置的标识符注入 由控制器接收 self.jsContext[@"App"] = self; //异常处理 self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; NSLog(@"异常信息:%@", exceptionValue); };}

此间表明下 self.jsContext[@"App"] = self;对应JS中的代码

<body ><div > <a onClick="javascript:history.back;">返回</a> <h2>购物车</h2> <a >编辑</a></div><script> $(function(){ $(".showde").click(function(){ App.edit</script></body>

那是UIWebView与JS交互的关键所在, JavaScriptCore框架会透过class_copyProtocolList方法找到类所服从的协商,然后再对每个左券通过protocol_copyProtocolList检查它是不是比照JSExport合计进而将艺术反映到JavaScript之中。直白的说正是调用当地点法之后从左券中收取相呼应的章程在JavaScript中调用.

有关充裕管理:在JSContext中奉行的JavaScript假使出现相当,只会被JSContext捕获并蕴藏在exception属性上,而不会向外抛出。时时随处检查JSContext对象的exception是还是不是不为nil鲜明是不适当,更合理的秘技是给JSContext对象设置exceptionHandler,它承受的是^(JSContext *context, JSValue *exceptionValue)情势的Block。其暗中同意值正是将盛传的exceptionValue赋给传入的context的exception属性.iOS7新JavaScriptCore框架入门介绍

#import <Foundation/Foundation.h>#import <MapKit/MapKit.h>@interface CustomOverlay : NSObject<MKOverlay>@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;@property (nonatomic, readonly) MKMapRect boundingMapRect;- initWithRect:(MKMapRect)rect;@end

回来的是NSXMLParser,必要我们温馨深入分析

Block

能够从一定水平上化解JSContext援用遭受变量与调整器self的循环引用难点Native中的代码

- webViewDidFinishLoad:(UIWebView *)webView{ //获取网页上下文环境 self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; __weak typeof weakSelf = self; //Block可以传入JSContext中当做JavaScript的方法使用 self.context[@"goBack"] = ^() { NSLog(@"点击返回按钮"); dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.navigationController popViewControllerAnimated:YES]; }); }; self.context[@"goShopping"] = ^() { NSLog(@"点击购物车按钮"); //获取参数列表 NSArray *args = [JSContext currentArguments]; for (JSValue *jsVal in args) { NSLog(@"%@", jsVal); } //获取当前调用该方法的对象 JSValue *this = [JSContext currentThis]; NSLog(@"this: %@",this); [weakSelf goTo]; };}- goTo{ //将参数传进去来调用JS的方法 [self.context evaluateScript:@"go"];}

JS中的代码

<body><div > <a onclick="goBack()">返回</a> <h2>商品详情</h2> <a onclick="goShopping(['商品1','商品2'])">购物车</a></div><script> function go{ alert; }</script></body>

适配iOS8.0,相较于UIWebView,品质功效方面都有了比很大的晋级,倘若项目无需适配iOS7的话能够直接使用WKWebView.简介一下代理左券:

  1. WKNavigationDelegate: UIWebViewDelegate的功用都有,何况加多了页面导航和网页加载进程的监听
  2. WKUIDelegate: 监听JS方法中的alert、confirm、prompt
  3. WKScriptMessageHandler: JS交互相关
@interface WKWebViewController ()<WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler>@property (strong ,nonatomic) WKWebView *webView;@end

- viewDidLoad { [super viewDidLoad]; //初始化 //_webView = [[WKWebView alloc]initWithFrame:self.view.bounds]; //带有设置选项的初始化 WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init]; _webView = [[WKWebView alloc]initWithFrame:self.view.bounds configuration:configuration]; //设置代理 _webView.navigationDelegate = self; _webView.UIDelegate = self; //加载本地的HTML NSURL *url = [[NSBundle mainBundle] URLForResource:@"shopsDetail_WKWebView" withExtension:@"html"]; [_webView loadRequest:[NSURLRequest requestWithURL:url]]; [self.view addSubview:_webView]; //添加一个名称,可以在JS中通过这个名称发送消息 [[_webView configuration].userContentController addScriptMessageHandler:self name:@"goBackApp"]; [[_webView configuration].userContentController addScriptMessageHandler:self name:@"goShoppingApp"];}

/** * WKScriptMessageHandler协议中必须要实现的方法 用来接收JS端通过window.webkit.messageHandlers.{Name}.postMessage()方法发送的消息并做相应处理 */- userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"方法名 %@,传回参数 %@",message.name,message.body); //根据方法名来区分 if ([message.name isEqual:@"goBackApp"]) { [self.navigationController popViewControllerAnimated:YES]; }else if ([message.name isEqual:@"goShoppingApp"]){ //调用JS中的方法并将参数传递到JS中 [self.webView evaluateJavaScript:@"altertFromOC('商品1,商品2')" completionHandler:nil]; }}

JS中代码

<body><div > <a onclick="goBack()">返回</a> <h2>商品详情</h2> <a onclick = "goShopping()">购物车</a></div><script> //接收Native发来的消息 function altertFromOC{ alert; } function goBack() { 将goBackApp发送Native window.webkit.messageHandlers.goBackApp.postMessage; } function goShopping(){ 将goBackApp发送Native中,并携带参数{shopsName:'商品名',shopsID:'商品ID'} window.webkit.messageHandlers.goShoppingApp.postMessage({shopsName:'商品名',shopsID:'商品ID'}) }</script></body>

在WKWebView中,网页自己的alert、confirm、prompt等艺术是被阻碍的,不论是不是有WKUIDelegate.为了能将传递至JS的参数字突显示出来,这里调用WKUIDelegate的代理方法.

/** * WKUIDelegate 代理方法 用来监听webView中的alert方法 * */- webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:completionHandler { //调用原生的alert方法 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:message preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(); }]]; [self presentViewController:alert animated:YES completion:NULL];}//用来监听webView中的confirm方法//- webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(BOOL result))completionHandler;//用来监听webView中的prompt方法//- webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(NSString * __nullable result))completionHandler;

Ok,交互方面大概就这几个剧情,关于WKWebView的代办方法还会有众多,用起来也很方便,这里就从未写了,究竟核心是关于相互的.代码在此处

References:

CustomOverlay.m实现:

借使回到的数量既不是JSON亦非XML那么须求设置

#import "CustomOverlay.h"@interface CustomOverlay ()@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;@property (nonatomic, readwrite) MKMapRect boundingMapRect;@end@implementation CustomOverlay@synthesize coordinate = _coordinate;@synthesize boundingMapRect = _boundingMapRect;#pragma mark - Initalize- initWithRect:(MKMapRect)rect{ if (self = [super init]) { self.boundingMapRect = rect; } return self;}@end
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

本文由小鱼儿玄机30码发布于编程,转载请注明出处:最近写简书不多,GET请求也可以将参数放在字典

关键词: 小鱼儿玄机30码