关于ios:MobPush-iOS推送功能最佳实现推荐

推送注册最佳实现,倡议在appdelegate里对推送的环境和告诉性能进行注册,外部办法为异步解决,不会阻塞主线程。参考如下代码: #import <MobPush/MobPush.h>- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ // 设置推送环境 特地留神,setAPNsForProduction:YES 的时候,须要我的项目打成release包解决,不能够间接应用xcode的debug和release环境#ifdef DEBUG [MobPush setAPNsForProduction:NO];#else [MobPush setAPNsForProduction:YES];#endif //MobPush推送设置(取得角标、声音、弹框揭示权限) MPushNotificationConfiguration *configuration = [[MPushNotificationConfiguration alloc] init]; configuration.types = MPushAuthorizationOptionsBadge | MPushAuthorizationOptionsSound | MPushAuthorizationOptionsAlert; [MobPush setupNotification:configuration]; return YES;}注册推送监听注册监听,能够监听到对于推送音讯的达到和点击,参考如下代码: //此办法须要在AppDelegate的 didFinishLaunchingWithOptions 办法外面注册 可参考Demo[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMessage:) name:MobPushDidReceiveMessageNotification object:nil];解决回调,解析参数在回调中解决MobPush对于告诉的监听,留神如果利用处于后盾或者被杀死状态,须要点击告诉音讯触发,参考如下代码: // 收到告诉回调- (void)didReceiveMessage:(NSNotification *)notification{ MPushMessage *message = notification.object; // 推送相干参数获取示例请在各场景回调中对参数进行解决 // NSString *body = message.notification.body; // NSString *title = message.notification.title; // NSString *subtitle = message.notification.subTitle; // NSInteger badge = message.notification.badge; // NSString *sound = message.notification.sound; // NSLog(@"收到告诉:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%ld,\nsound:%@,\n}",body, title, subtitle, (long)badge, sound); switch (message.messageType) { case MPushMessageTypeCustom: {// 自定义音讯回调 } break; case MPushMessageTypeAPNs: {// APNs回调 } break; case MPushMessageTypeLocal: {// 本地告诉回调 } break; case MPushMessageTypeClicked: {// 点击告诉回调 } default: break; }}

September 14, 2022 · 1 min · jiezi

关于ios:基于自建-VTree-的全链路埋点方案

本文作者: dl一、背景 在以后挪动互联网时代,一个产品想疾速、精确的抢占市场,无疑是须要产品疾速迭代更新,如何帮助产品经理对产品以后的数据做出最优判断是要害,这就须要客户端侧提供高精度、稳固、全链路的埋点数据;做客户端开发的同学都粗浅晓得,想要在开发过程中满足上述三点,开发过程都是头大的; 针对这个问题,咱们自研了一套全链路埋点计划,从埋点设计、到客户端三端(iOS、Android、H5)开发、以及埋点校验&稽查、再到埋点数据应用,目前曾经广泛应用于云音乐各个次要APP。 二、先聊聊传统埋点计划的弊病 传统埋点,就是BI数据人员依据策动想要的数据,设计出一个个的单点的坑位埋点,而后客户端人员一一埋进来,这些埋点常常都存在以下特点: 坑位的事件埋点很简略:点击/双击/滑动等明确的事件类埋点,很简略,依据需要一个一个埋下来即可资源位曝光埋点是噩梦:在列表/非列表资源的曝光埋点场景,想做到高精度(埋点精度提到 99.99%)难度很大,你有可能每一个曝光埋点都须要思考如下大部分场景:每个坑位都是独立的:坑位之间的埋点没有关系,须要给每一个坑位起名字(比方通过随机字符串,或者组合参数来标识),页面、列表、元素之间,存在大量的反复参数,以达到数据分析要求漏斗/归因剖析难:因为每一个坑位埋点都是独立的,APP应用过程中先后产生的埋点是无关联的,想要做到漏斗/归因剖析,须要客户端做魔鬼参数传递,而后数据分析时再一一场景的做参数关联剖析坑位黑盒:想晓得一个app有多少坑位埋点,以后页面下曾经显现出了多少坑位,坑位之间是什么关系,治理老本高三、咱们已经做过的一些尝试3.1 无痕埋点 市面上有很多人介绍无痕埋点,咱们已经也做过相似的尝试;这种无痕,次要是针对一些坑位事件(比方点击、双击、滑动等事件)埋点做主动生成埋点,同时附带上生成的xpath(依据view层级生成),而后把埋点上报到数据平台后,再将xpath赋予实在的业务意义,从而能够进行数据分析; 然而这个计划的问题是只能解决一些简略事件场景,并且数据平台做xpath关联是一件噩梦,工作量大,最次要的是不稳固,对于埋点数据高精度场景,这个计划不可行(没有哪个客户端开发人员天天破费大量工夫查找 xpath 是什么意义,以及随着迭代业务的开发,xpath因为不受管制的变动带来的数据问题带来的排查工作量是微小的)。 特地对于资源位的曝光上,想要做到真正的无痕,主动埋点,是不太可行的;比方列表场景,底层是不意识一个cell是什么资源的,甚至都也不晓得是不是一个资源。 四、咱们的计划4.1 对象对象是咱们计划埋点治理和开发的根本单位,给一个UIView设置 _oid(对象Id: Object Id),该view就是一个对象; 对象分为两大类,page & element; page对象: 比方 UIViewController.view, WebView, 或者一个半屏浮层的view,再或者一个业务弹窗element对象: 比方 UIButton, UICollectionViewCell, 或者一个自定义view对象参数: 对象是埋点具体信息的承载体,承载着对象维度的具体埋点参数对象的复用: 对象的存在,其中一个很大的起因,就是须要做复用,对于一些通用UI组件,尤为适合4.2 虚构树(VTree)对象不是孤立存在的,而是以虚构树(VTree)的形式组合在一起的, 上面是一个示例: 虚构树VTree有如下特点: View树子集: 原始view树层级很简单,被标识成对象的称为节点,所有节点就组合成了VTree,是原始view树的子集上下文: 虚构树中的对象,是存在高低关系的,一个节点的所有先人节点,就是该对象(节点)的上下文对象参数: 有了节点的高低层级,不同维度的对象,只关怀本人维度的参数,比方歌单详情页中歌曲cell不关怀页面申请级别的歌单idSPM: 节点及其所有先人结点的oid组成了SPM值(其实还有position参数的参加,稍后再详解),该SPM能够惟一定位该节点继续生成: VTree是源源不断的构建的,每一个view产生了变动,View的增加/删除/层级变动/位移/大小变动/hidden/alpha,等等,都会引起从新构建一颗新的VTree五、埋点的产生下面的计划介绍完之后,你肯定存在很多纳闷,有了对象,有了虚构树,对象有了参数,埋点在哪儿? 5.1 先来看下埋点格局一个埋点除了有事件类型(action), 埋点工夫等一些根本信息之外,还得有业务埋点参数,以及能体现出对象上下级的构造 先来看下一个一般埋点的格局: { "_elist": [ { "_oid": "【必选】元素的oid", "_pos": "【可选】,业务方配置的地位信息", "biz_param": "【按需】业务参数" } ], "_plist": [ { "_oid": "【必选】page的oid", "_pos": "【可选】,业务方配置的地位信息", "_pgstep": "【必选】, 该page/子page曝光时的页面深度" } ], "_spm": "【必选】这里形容的是节点的“地位”信息,用来定位节点", "_scm": "【必选】这里形容的是节点的“内容”信息,用来形容节点的内容", "_sessid": "【必选】冷启动生成,会话id", "_eventcode": "【必选】事件: _ec/_ev/_ed/_pv/_pd", "_duration": "数字,毫秒单位"}_eventcode: 埋点的类型,比方元素点击(_ec), 元素曝光开始(_ev), 元素曝光完结(_ed), 页面曝光开始(_pv), 页面曝光完结(_pd) 等等_elist: 从以后元素节点开始,向上所有元素节点的汇合,是一个数组,顺叙_plist: 从以后节点开始,向上所有页面结点的即可,是一个数组,顺叙_spm: 下面曾经介绍(SPM),能够惟一定位该坑位从下面的数据结构能够看出,数据结构是结构化的,坑位不是独立的,存在层级关系的5.2 点击事件大部分的点击事件,都产生在如下四个场景上: ...

September 14, 2022 · 5 min · jiezi

关于ios:iOS逆向某不知名App越狱检测

1.指标此篇文本为入门文章,大家莫抱过多冀望。此文章的目标是教大家如何从UI动手,去定位本人想要的货色。2.操作环境 mac零碎frida-ios-dump:砸壳已越狱iOS设施:脱壳及frida调试IDA Pro:动态剖析 3.流程寻找切入点启动App后,界面如下图: IMG_67EF545277E4-1剖析过程从界面能够看出,App检测到越狱后,会弹出一个弹窗,文案为越狱手机存在平安危险,做iOS开发的都晓得,最终这文案显示前,会调用UILabel类的setText:办法。咱们trace该办法并打印堆栈:js代码:{  onEnter(log, args, state) {    log(-[UILabel setText:${new ObjC.Object(args[2])}]);   log('UILabel setText called from:\n' +         Thread.backtrace(this.context, Backtracer.ACCURATE)         .map(DebugSymbol.fromAddress).join('\n') + '\n');  },  onLeave(log, retval, state) {  }}要害日志如下:-[UILabel setText:越狱手机存在平安危险]UILabel setText called from:0x1eaa7d0f4 UIKitCore!-[_UIAlertControllerView _updateMessageLabelContents]0x1eaa756f8 UIKitCore!-[_UIAlertControllerView _prepareMesssageLabel]0x1eaa750f8 UIKitCore!-[_UIAlertControllerView _prepareViewsAndAddConstraints]0x1eaa75048 UIKitCore!-[_UIAlertControllerView setAlertController:]0x1eaa61740 UIKitCore!-[UIAlertController loadView]0x1ead35ed8 UIKitCore!-[UIViewController loadViewIfRequired]0x1ead36628 UIKitCore!-[UIViewController view]0x1ead4ddd4 UIKitCore!-[UIViewController _setPresentationController:]0x1ead461f4 UIKitCore!-[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:]0x1ead47ccc UIKitCore!-[UIViewController _presentViewController:withAnimationController:completion:]0x1ead4a3a8 UIKitCore!__63-[UIViewController _presentViewController:animated:completion:]_block_invoke0x1ead4a8a4 UIKitCore!-[UIViewController _performCoordinatedPresentOrDismiss:animated:]0x1ead4a300 UIKitCore!-[UIViewController _presentViewController:animated:completion:]0x1ead4a560 UIKitCore!-[UIViewController presentViewController:animated:completion:]0x10128253c GeneralApp!0xd253c (0x1000d253c)0x1be344a38 libdispatch.dylib!_dispatch_call_block_and_release应用frida-ios-dump砸壳后,再应用IDA Pro编译ipa文件。跳转到内存0x1000d253c地位 image-20220911160319867再按F5:__int64 __fastcall sub_1000D24D4(_QWORD a1){  void v1; // x19  __int64 v2; // x20  void *v4; // [xsp+8h] [xbp-38h]  __int64 v5; // [xsp+10h] [xbp-30h]  __int64 (__fastcall v6)(); // [xsp+18h] [xbp-28h]  void v7; // [xsp+20h] [xbp-20h]  __int64 v8; // [xsp+28h] [xbp-18h]  v1 = (void )a1[4];  v2 = a1[5];  v4 = _NSConcreteStackBlock;  v5 = 3254779904LL;  v6 = sub_1000D2554;  v7 = &unk_101A29970;  v8 = objc_retain(a1[6]);  objc_msgSend(v1, "presentViewController:animated:completion:", v2, 1LL, &v4);  return objc_release(v8);}查找sub_1000D24D4函数的穿插援用,一层一层往上找,最终找到如下函数:void __cdecl -UIViewController cft_presentViewController:presentType:presentCompletionHandler:dismissCompleteHandler:{  id v6; // x21  id v7; // x20  UIViewController v8; // x24  void v9; // x19  __int64 v10; // x20  __int64 v11; // x21  void v12; // x0  __int64 v13; // x22  dispatch_semaphore_t v14; // x23  void v15; // x0  void v16; // x24  void v17; // x0  void v18; // x0  void v19; // x27  void v20; // x0  __int64 v21; // x28  void v22; // x0  void v23; // x0  void v24; // x25  void v25; // x0  __int64 v26; // x26  __int64 v27; // [xsp+8h] [xbp-A8h]  void v28; // [xsp+10h] [xbp-A0h]  __int64 v29; // [xsp+18h] [xbp-98h]  __int64 (__fastcall v30)(__int64); // [xsp+20h] [xbp-90h]  void v31; // [xsp+28h] [xbp-88h]  __int64 v32; // [xsp+30h] [xbp-80h]  __int64 v33; // [xsp+38h] [xbp-78h]  __int64 v34; // [xsp+40h] [xbp-70h]  UIViewController v35; // [xsp+48h] [xbp-68h]  __int64 v36; // [xsp+50h] [xbp-60h]  __int64 v37; // [xsp+58h] [xbp-58h]  v6 = a6;  v7 = a5;  v8 = self;  v9 = (void )objc_retain(a3);  v10 = objc_retain(v7);  v11 = objc_retain(v6);  v37 = 0LL;  v12 = objc_msgSend(          v9,          "aspect_hookSelector:withOptions:usingBlock:error:",          "viewDidDisappear:",          0LL,          &off_101A2BF98,          &v37);  objc_unsafeClaimAutoreleasedReturnValue(v12);  v13 = objc_retain(v37);  if ( !v13 )  {    v14 = dispatch_semaphore_create(0LL);    v28 = _NSConcreteStackBlock;    v29 = 3254779904LL;    v30 = sub_1000D23A0;    v31 = &unk_101A2BFB8;    v32 = objc_retain(v9);    v33 = objc_retain(v11);    v27 = objc_retain(v14);    v34 = v27;    v35 = v8;    v36 = objc_retain(v10);    v15 = objc_msgSend(&OBJC_CLASS___NSBlockOperation, "blockOperationWithBlock:", &v28);    v16 = (void )objc_retainAutoreleasedReturnValue(v15);    v17 = objc_msgSend((void )qword_101F71BF8, "operations");    v18 = (void )objc_retainAutoreleasedReturnValue(v17);    v19 = v18;    v20 = objc_msgSend(v18, "lastObject");    v21 = objc_retainAutoreleasedReturnValue(v20);    objc_release(v21);    objc_release(v19);    if ( v21 )    {      v22 = objc_msgSend((void )qword_101F71BF8, "operations");      v23 = (void )objc_retainAutoreleasedReturnValue(v22);      v24 = v23;      v25 = objc_msgSend(v23, "lastObject");      v26 = objc_retainAutoreleasedReturnValue(v25);      objc_msgSend(v16, "addDependency:", v26);      objc_release(v26);      objc_release(v24);    }    objc_msgSend((void *)qword_101F71BF8, "addOperation:", v16);    objc_release(v16);    objc_release(v36);    objc_release(v34);    objc_release(v33);    objc_release(v32);    objc_release(v27);  }  objc_release(v13);  objc_release(v11);  objc_release(v10);  objc_release(v9);}接下来,同时跟踪UILabel的setText:办法和UIViewController的cft_presentViewController:presentType:presentCompletionHandler:dismissCompleteHandler:办法,获取到日志如下:-[UIViewController cft_presentViewController:0x104928e00 presentType:0x1 presentCompletionHandler:0x16ec4e5a8 dismissCompleteHandler:0x16ec4e580]UIViewController cft_presentViewController called from:0x1012b9fdc GeneralApp!+[CFTAlertPresentController presentAlertController:presentCompletionHandler:dismissCompleteHandler:]0x1012d464c GeneralApp!-[LaunchingViewController start]0x1012d3360 GeneralApp!0x123360 (0x100123360)0x1be3457d4 libdispatch.dylib!_dispatch_client_callout0x1be2f3c1c libdispatch.dylib!_dispatch_lane_barrier_sync_invoke_and_complete0x1012d3310 GeneralApp!0x123310 (0x100123310)0x1012b9978 GeneralApp!0x109978 (0x100109978)0x1eb76ad1c UIKitCore!-[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:]0x1eb741a74 UIKitCore!-[UIViewAnimationState sendDelegateAnimationDidStop:finished:]0x1eb742048 UIKitCore!-[UIViewAnimationState animationDidStop:finished:]0x1c2e573c8 QuartzCore!CA::Layer::run_animation_callbacks(void*)0x1be3457d4 libdispatch.dylib!_dispatch_client_callout0x1be2f3008 libdispatch.dylib!_dispatch_main_queue_callback_4CF$VARIANT$mp0x1be898b20 CoreFoundation!__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__0x1be893a58 CoreFoundation!__CFRunLoopRun0x1be892fb4 CoreFoundation!CFRunLoopRunSpecific-[UILabel setText:您的设施不平安]UILabel setText called from:0x1eaa7cfe8 UIKitCore!-[_UIAlertControllerView _updateTitleLabelContents]0x1eaa75544 UIKitCore!-[_UIAlertControllerView _prepareTitleLabel]0x1eaa750e8 UIKitCore!-[_UIAlertControllerView _prepareViewsAndAddConstraints]0x1eaa75048 UIKitCore!-[_UIAlertControllerView setAlertController:]0x1eaa61740 UIKitCore!-[UIAlertController loadView]0x1ead35ed8 UIKitCore!-[UIViewController loadViewIfRequired]0x1ead36628 UIKitCore!-[UIViewController view]0x1ead4ddd4 UIKitCore!-[UIViewController _setPresentationController:]0x1ead461f4 UIKitCore!-[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:]0x1ead47ccc UIKitCore!-[UIViewController _presentViewController:withAnimationController:completion:]0x1ead4a3a8 UIKitCore!__63-[UIViewController _presentViewController:animated:completion:]_block_invoke0x1ead4a8a4 UIKitCore!-[UIViewController _performCoordinatedPresentOrDismiss:animated:]0x1ead4a300 UIKitCore!-[UIViewController _presentViewController:animated:completion:]0x1ead4a560 UIKitCore!-[UIViewController presentViewController:animated:completion:]0x10128253c GeneralApp!0xd253c (0x1000d253c)0x1be344a38 libdispatch.dylib!_dispatch_call_block_and_release-[UILabel setText:越狱手机存在平安危险]UILabel setText called from:0x1eaa7d0f4 UIKitCore!-[_UIAlertControllerView _updateMessageLabelContents]0x1eaa756f8 UIKitCore!-[_UIAlertControllerView _prepareMesssageLabel]0x1eaa750f8 UIKitCore!-[_UIAlertControllerView _prepareViewsAndAddConstraints]0x1eaa75048 UIKitCore!-[_UIAlertControllerView setAlertController:]0x1eaa61740 UIKitCore!-[UIAlertController loadView]0x1ead35ed8 UIKitCore!-[UIViewController loadViewIfRequired]0x1ead36628 UIKitCore!-[UIViewController view]0x1ead4ddd4 UIKitCore!-[UIViewController _setPresentationController:]0x1ead461f4 UIKitCore!-[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:]0x1ead47ccc UIKitCore!-[UIViewController _presentViewController:withAnimationController:completion:]0x1ead4a3a8 UIKitCore!__63-[UIViewController _presentViewController:animated:completion:]_block_invoke0x1ead4a8a4 UIKitCore!-[UIViewController _performCoordinatedPresentOrDismiss:animated:]0x1ead4a300 UIKitCore!-[UIViewController _presentViewController:animated:completion:]0x1ead4a560 UIKitCore!-[UIViewController presentViewController:animated:completion:]0x10128253c GeneralApp!0xd253c (0x1000d253c)0x1be344a38 libdispatch.dylib!_dispatch_call_block_and_release在cft_presentViewController:presentType:presentCompletionHandler:dismissCompleteHandler:办法的调用栈,发现[LaunchingViewController start]办法,应用ida pro查看该函数:void __cdecl -LaunchingViewController start{  if ( !(~LODWORD(self->_launchAchieveOption) & 0x1FLL) )  {    v2 = self;    self->_launchAchieveOption = 0LL;    v3 = ((id (__cdecl )(GuaTabBarController_meta , SEL))objc_msgSend)(           (GuaTabBarController_meta )&OBJC_CLASS___GuaTabBarController,           "shareTabBarController");    v4 = objc_retainAutoreleasedReturnValue(v3);    v23 = _NSConcreteStackBlock;    v24 = 3254779904LL;    v25 = sub_100124684;    v26 = &unk_101A2BC20;    v5 = (void )objc_retain(v4);    v27 = v5;    v28 = v2;    +NaviService naviModelWithNaviRoot:withNaviHead:withSourceFrom:ret:;    if ( v2->_adDetailDisplayController )    {      v6 = objc_msgSend(v5, "viewControllers", v23, v24, v25, v26);      v7 = (void )objc_retainAutoreleasedReturnValue(v6);      v8 = v7;      v9 = objc_msgSend(v7, "objectAtIndexedSubscript:", 0LL, v23, v24, v25, v26);      v10 = (void )objc_retainAutoreleasedReturnValue(v9);      objc_msgSend(v10, "pushViewController:animated:", v2->_adDetailDisplayController, 1LL, v23, v24, v25, v26);    }    v11 = objc_msgSend(&OBJC_CLASS___UIApplication, "sharedApplication", v23, v24, v25, v26);    v12 = (void )objc_retainAutoreleasedReturnValue(v11);    v13 = v12;    v14 = objc_msgSend(v12, "delegate", v23, v24, v25, v26);    v15 = (void )objc_retainAutoreleasedReturnValue(v14);    v16 = v15;    v17 = objc_msgSend(v15, "window", v23, v24, v25, v26);    v18 = (void )objc_retainAutoreleasedReturnValue(v17);    objc_msgSend(v18, "setRootViewController:", v5, v23, v24, v25, v26);    if ( (unsigned int)+CFTJailBreakJudge deviceIsJailBreak )    {      v19 = objc_msgSend(              &OBJC_CLASS___UIAlertController,              "alertControllerWithTitle:message:preferredStyle:",              CFSTR("您的设施不平安"),              CFSTR("越狱手机存在平安危险"),              1LL,              v23,              v24,              v25,              v26);      v20 = (void )objc_retainAutoreleasedReturnValue(v19);      v21 = objc_msgSend(              &OBJC_CLASS___UIAlertAction,              "actionWithTitle:style:handler:",              CFSTR("确定"),              0LL,              0LL,              v23,              v24,              v25,              v26);      v22 = objc_retainAutoreleasedReturnValue(v21);      objc_msgSend(v20, "addAction:", v22, v23, v24, v25, v26);      +CFTAlertPresentController presentAlertController:;    }  }}从函数中可发现越狱检测函数为[CFTJailBreakJudge deviceIsJailBreak]:bool __cdecl +CFTJailBreakJudge deviceIsJailBreak{  CFTJailBreakJudge_meta v2; // x20  void v3; // x0  __int64 v4; // x0  void v5; // x0  void v6; // x19  void v7; // x0  void v8; // x22  __int64 v9; // x25  unsigned __int64 v10; // x26  uint32_t v11; // w0  uint32_t v12; // w20  uint32_t v13; // w21  void v14; // x25  const char v15; // x0  void v16; // x25  char v17; // w26  _BOOL8 v18; // x20  bool result; // w0  __int128 v20; // [xsp+0h] [xbp-140h]  __int128 v21; // [xsp+10h] [xbp-130h]  __int128 v22; // [xsp+20h] [xbp-120h]  __int128 v23; // [xsp+30h] [xbp-110h]  char v24; // [xsp+40h] [xbp-100h]  const __CFString v25; // [xsp+C0h] [xbp-80h]  const __CFString v26; // [xsp+C8h] [xbp-78h]  const __CFString v27; // [xsp+D0h] [xbp-70h]  const __CFString v28; // [xsp+D8h] [xbp-68h]  const __CFString v29; // [xsp+E0h] [xbp-60h]  __int64 v30; // [xsp+E8h] [xbp-58h]  v2 = self;  v25 = CFSTR("/Applications/Cydia.app");  v26 = CFSTR("/Library/MobileSubstrate/MobileSubstrate.dylib");  v27 = CFSTR("/bin/bash");  v28 = CFSTR("/usr/sbin/sshd");  v29 = CFSTR("/etc/apt");  v3 = objc_msgSend(&OBJC_CLASS___NSArray, "arrayWithObjects:count:", &v25, 5LL);  v4 = objc_retainAutoreleasedReturnValue(v3);  v20 = 0u;  v21 = 0u;  v22 = 0u;  v23 = 0u;  v5 = (void )objc_retain(v4);  v6 = v5;  v7 = objc_msgSend(v5, "countByEnumeratingWithState:objects:count:", &v20, &v24, 16LL, 0LL);  if ( v7 )  {    v8 = v7;    v9 = (_QWORD )v21;    while ( 2 )    {      v10 = 0LL;      do      {        if ( (_QWORD )v21 != v9 )          objc_enumerationMutation(v6);        if ( (unsigned __int64)objc_msgSend(                                 v2,                                 "permissionForFile:",                                 (_QWORD )(((_QWORD )&v20 + 1) + 8  v10),                                 (_QWORD)v20) & 1 )        {          objc_release(v6);          goto LABEL_16;        }        ++v10;      }      while ( v10 < (unsigned __int64)v8 );      v8 = objc_msgSend(v6, "countByEnumeratingWithState:objects:count:", &v20, &v24, 16LL, (_QWORD)v20);      if ( v8 )        continue;      break;    }  }  objc_release(v6);  if ( !((unsigned __int64)objc_msgSend(v2, "permissionForFile:", CFSTR("/User/Applications/"), (_QWORD)v20) & 1) )  {    v11 = _dyld_image_count();    if ( !v11 )    {LABEL_14:      v18 = getenv("DYLD_INSERT_LIBRARIES") != 0LL;      goto LABEL_17;    }    v12 = v11;    v13 = 0;    while ( 1 )    {      v14 = (void *)objc_alloc(&OBJC_CLASS___NSString);      v15 = _dyld_get_image_name(v13);      v16 = objc_msgSend(v14, "initWithUTF8String:", v15, (_QWORD)v20);      v17 = (unsigned __int64)objc_msgSend(v16, "containsString:", CFSTR("MobileSubstrate.dylib"), (_QWORD)v20);      objc_release(v16);      if ( v17 & 1 )        break;      if ( v12 == ++v13 )        goto LABEL_14;    }  }LABEL_16:  v18 = 1;LABEL_17:  return v18;}后果1、检测以下门路是否存在: /Applications/Cydia.app/Library/MobileSubstrate/MobileSubstrate.dylib/bin/bash/usr/sbin/sshd/etc/apt2、如果门路/User/Applications/不存在,检测getenv("DYLD_INSERT_LIBRARIES")是否存在3、如果门路/User/Applications/不存在,检测以后当初在运行的动静库是否蕴含MobileSubstrate.dylibEnd浏览此文档的过程中遇到任何问题,请关注公众号【挪动端Android和iOS开发技术分享】或加QQ群【812546729】

September 11, 2022 · 1 min · jiezi

关于ios:iOS端如何实现带UI截屏分享

下载资源文件1.1 须要开发者 点击这里 来下载分享的demo1.2 须要 点击这里 下载SDK 导入SDK以及相干文件须要导入下载的SDK资源文件以及UI截屏所须要的6个文件,如下图:留神:在导入的过程中,须要勾选以下3个:增加依赖库 点击 “+” 号,并在弹框里输出以下依赖库,进行增加必要依赖库:libc++.tbdlibz.tbdlibsqlite3.tbd 初始化SDK在我的项目默认的plist文件里 配置ShareSDK的AppKey和AppSecret,键别离为 MOBAppKey 和 MOBAppSecret ,值为之前在MobTech官网开发者后盾申请的AppKey和AppSecret( 留神配置之后保留好,而后看我的项目的Info选项里有没有 ) 初始化第三方平台在Appdelegate.m里的启动办法didFinishLaunchingWithOptions中退出初始化的办法以及启动截屏监听的办法,如下: #import "MobScreenshotCenter.h"#import <ShareSDK/ShareSDK.h>- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ [ShareSDK registPlatforms:^(SSDKRegister *platformsRegister) { //QQ [platformsRegister setupQQWithAppId:@"100371282" appkey:@"aed9b0303e3ed1e27bae87c33761161d" enableUniversalLink:YES universalLink:@"https://70imc.share2dlink.com/qq_conn/100371282"]; //更新到4.3.3或者以上版本,微信初始化须要应用以下初始化 [platformsRegister setupWeChatWithAppId:@"wx617c77c82218ea2c" appSecret:@"c7253e5289986cf4c4c74d1ccc185fb1" universalLink:@"https://70imc.share2dlink.com/"]; //新浪 [platformsRegister setupSinaWeiboWithAppkey:@"568898243" appSecret:@"38a4f8204cc784f81f9f0daaf31e02e3" redirectUrl: @"http://www.sharesdk.cn" universalLink:@"https://70imc.share2dlink.com/"]; }]; //启动截屏监听 [[MobScreenshotCenter shareInstance] start]; return YES;}以上几步就能够实现带UI的截屏分享,开发者如果要批改结构分享参数的话,能够在这里批改 批改分享参数 截屏UI成果展现留神UI有2种UI款式:第一种:全屏幕次要界面效果图:第二种:提醒界面须要换以下办法类型 [self _screenCaptureShareWithMode:SSEScreenCaptureUIModeAlert duration:3.0 useClientShare:YES];效果图:

September 7, 2022 · 1 min · jiezi

关于ios:iOS端如何实现微信分享链接与登陆

下载SDK1.1 登录官网1.2 点击这里 下载SDK1.3 勾选本人须要的平台,例如微信平台,而后本人写UI,只须要勾选 如下图:点击保留配置之后,而后点击 下载 即可 导入SDK将1.3步获取到的SDK,间接将整个SDK资源文件拖进我的项目里,如下图:并且勾选以下3个选项在点击Finish,实现导入。 增加依赖库 点击 “+” 号,并在弹框里输出以下依赖库,进行增加 必要依赖库:libc++.tbdlibz.tbdlibsqlite3.tbd 配置-ObjC在我的项目的Build Settings中的Other Linker Flags增加”-ObjC” ,留神大小写 配置ATS在我的项目的info.plist中增加 App Transport Security Settings,类型为字典类型给它增加一个Key:Allow Arbitrary Loads,类型为Boolean类型,值为YES; 配置URL Scheme关上我的项目Info选项,找到URL Types,增加微信的URL Scheme:初始化里的AppId就是URL SCheme,如下图: 配置白名单在我的项目的info.plist中增加LSApplicationQueriesSchemes,类型为Array而后给它增加一个须要反对的我的项目,类型为字符串类型:微信白名单须要减少:wechat,weixin,weixinULAPI这3项,如下图:留神:XCode13,iOS15上编译,白名单只读取前50个配置,前面配置的都会有效 配置Universal LinkUniversal Link能够本人去生成,参考苹果官网文档,然而为了不便用户,节俭用户的工夫和精力,咱们也在后盾为客户生成了Universal Link,如下图:Team id:开发者团队的ID,可在苹果开发者后盾查看Bundle id:开发者账号下所有利用对应一个Bundle id,可见于我的项目plist文件中的Bundle identifier,务必与我的项目中保持一致填写好这些信息保留之后,就能够将生成的Universal Link用于微信开放平台上,微信初始化里,我的项目里这3个中央进行配置 (1)微信里以 https://结尾,反斜杠结尾 这种模式填写如下:(2)微信初始化里与微信开放平台一样模式以 https://结尾,反斜杠结尾 模式填写如下: [platformsRegister setupWeChatWithAppId:@"wx617c77c82218ea2c" appSecret:@"c7253e5289986cf4c4c74d1ccc185fb1" universalLink:@"https://70imc.share2dlink.com/"];(3)我的项目里以applinks:XXXX模式填写如下:增加Associated Domains(留神:证书必须开明这个性能哦)而后双击Associated Domains增加好点击 + 号,进行UL 配置,如下: 初始化SDK在我的项目默认的plist文件里 配置ShareSDK的AppKey和AppSecret,键别离为 MOBAppKey 和 MOBAppSecret ,值为之前在MobTech官网开发者后盾申请的AppKey和AppSecret( 留神配置之后保留好,而后看我的项目的Info选项里有没有 ) 初始化微信平台我的项目启动的时候在 application:didFinishLaunchingWithOptions:中增加初始化第三方平台的办法 #import <ShareSDK/ShareSDK.h>- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ [ShareSDK registPlatforms:^(SSDKRegister *platformsRegister) { [platformsRegister setupWeChatWithAppId:@"wx617c77c82218ea2c" appSecret:@"c7253e5289986cf4c4c74d1ccc185fb1" universalLink:@"https://70imc.share2dlink.com/"]; }]; return YES;}结构分享参数以及调用分享办法可在本人须要登录的视图页面写一个分享按钮,而后在按钮事件里调用接口,代码如下: ...

September 7, 2022 · 2 min · jiezi

关于ios:用-Rust-开发跨平台-App-探索和实践

FeatureProbe 作为一个开源的『性能』治理服务,蕴含了灰度放量、AB试验、实时配置变更等针对『性能粒度』的一系列治理操作。须要提供各个语言的 SDK 接入,其中就包含挪动端的 iOS 和 Android 的 SDK,那么要怎么解决跨平台 SDK 的问题呢? 一、为什么要跨平台?缩小人力老本,缩小开发工夫。两个平台共享一套代码,前期产品保护简略。二、目前常见的跨平台计划C++很多公司的跨平台挪动根底库根本都有 C++ 的影子,如微信,腾讯会议,还有晚期的 Dropbox,出名的开源库如微信的 Mars 等。益处是一套代码多端适配,然而须要大公司对 C++ 有弱小的工具链反对,还须要花重金延聘 C++ 研发人员,随着团队人员变动,产品保护老本也不可漠视,所以 Dropbox 前期也放弃了应用 C++ 的跨端计划。 Rust + FFIRust 和对应平台的 FFI 封装。常见的办法如飞书和 AppFlow 是通过相似 RPC 的理念,裸露大量的接口,用作数据传输。益处是复杂度可控,毛病是要进行大量的序列化和反序列化,同时代码的表白会受到限制,比方不好表白回调函数。 Flutter更适宜于有 UI 性能的跨平台残缺 APP 解决方案,不适用于跨平台挪动端 SDK 的计划。 三、为什么用 Rust ?开发成本不思考投入老本的话,原生计划在公布、集成和用户 Debug 等方面都会更有劣势。但思考到初创团队配置两个资深的研发人员来保护两套 SDK 须要面临老本问题。 有丰盛的 Rust 跨平台教训咱们之前有用过 Rust 实现过跨平台的网络栈,用 tokio 和 quinn 等高质量的 crate 实现了一个长连贯的客户端和服务端。 平安稳固(1) FeatureProbe 作为灰度公布的性能平台,肩负了降级的职责,对 SDK 的稳定性要求更高。 (2) 原生挪动端 SDK 一旦呈现多线程解体的问题,难以定位和排查,须要较长的修复周期。 ...

September 6, 2022 · 3 min · jiezi

关于ios:iOS逆向某营业厅算法分析

浏览此文档的过程中遇到任何问题,请关注公众号【挪动端Android和iOS开发技术分享】或加QQ群【812546729】 1.指标应用frida stalker剖析某营业厅的签名算法。 2.操作环境mac零碎frida-ios-dump:砸壳Charles:抓包已越狱iOS设施:脱壳及frida调试IDA Pro:动态剖析 3.流程 寻找切入点 在账号密码登录页,点击登录,通过Charles抓包获取到关键词为loginAuthCipherAsymmertric,这也就是咱们的切入点:  剖析过程应用frida-ios-dump的砸壳命令dump.py com.wemomo.momoappdemo1 砸壳获取到ipa文件,再应用IDA Pro编译ipa文件,而后搜寻搜寻字符串loginAuthCipherAsymmertric失败,持续搜寻userLoginNormal,失败。该利用对字符串都进行了混同。搜寻无果后,只能换个思路,尝试hook NSMutableURLRequest类。 应用frida-trace的frida-trace -UF -m "-[NSMutableURLRequest setHTTPBody:]"命令跟踪该函数,js代码如下: {  onEnter(log, args, state) {      var arg2 = new ObjC.Object(args[2])      log(`-[NSMutableURLRequest setHTTPBody:${arg2.bytes().readUtf8String()}]`);  },  onLeave(log, retval, state) {  }}点击登录后,获取到的日志如下: -[NSMu```tableURLRequest setHTTPBody:ndh=1&t=00%2F00%2F0000%2000%3A00%3A00%200%20-480&c.&v3=baoguang_event&deviceId=7B063D78-C5D8-45A6-8E3D-37B787DEB2CD&hitDate=2022-09-02%2023%3A01%3A52&currentPage=Denglujh-kuandaidenglushouji&v63=101-106&appVersion=4&c25=%E6%B6%88%E6%81%AF%2BSyjh-sytop-message-1_1%2B%28null%29%2B%28null%29&es_timestamp=1662130874519&v60=lo158b3b81&codeVersion=22033101&v65=WIFI&v61=disable&a.&action=trkAppBgAction&OSVersion=iOS%2012.5.5&DeviceName=iPhone7%2C2&RunMode=Application&AppID=CTPocket%209.4.0%20%284%29&CarrierName=%28null%29&Resolution=750x1334&TimeSinceLaunch=2536&.a&lunchtype=aut_lunch&.c&pev2=AMACTION%3AtrkAppBgAction&pageName=CTPocket%2F4&ce=UTF-8&aid=540B88F2280D4599-146C532D0B076319&pe=lnk_o&cp=foreground]-[NSMutableURLRequest setHTTPBody:{"content":{"fieldData":{"isChinatelecom":"0","phoneNum":"13245678901","authentication":"222222","accountType":"","deviceUid":"ddecc53e1fce414e9e89b6ea47e567e3","systemVersion":"12.5.5","loginAuthCipherAsymmertric":"o4Af5TvC5iV25FhTE9NIZJEiqHLWg+JkcCF4AGp727uhvFydBWvkCz8HauqTDpIoRhpfqLUMLN6Hk1ucBZOPYhCHwm4N\/4PuPsMWZTEbips+uL74ufgeLMci0nIZRmFsCsBrgvUVkebKcRo2yO0DZQ2jtnKe+cG78v6aOHl5ssk=","loginType":"4"},"attach":"iPhone"},"headerInfos":{"broadAccount":"","source":"120002","shopId":"20004","userLoginName":"13245678901","broadToken":"","code":"userLoginNormal","clientType":"#9.4.0#channel50#iPhone 6#","token":"","timestamp":"20220902230115","sourcePassword":"TiqmIZ"}}]-[NSMutableURLRequest setHTTPBody:ndh=1&t=00%2F00%2F0000%2000%3A00%3A00%200%20-480&c.&v3=hit_event&deviceId=7B063D78-C5D8-45A6-8E3D-37B787DEB2CD&hitDate=2022-09-02%2023%3A01%3A05&c20=%E5%8F%B3%E6%BB%91%E7%99%BB%E5%BD%95&appVersion=4&lastAction=Denglujh-denglu-mima-2_8%5E%E5%8F%B3%E6%BB%91%E7%99%BB%E5%BD%95&method=trkAppButtonClick%20-action%20...&v63=101-106&currentPage=Denglujh-kuandaidenglushouji&es_timestamp=1662130875056&c21=Denglujh-denglu-mima-2_8&v60=lo158b3b81&codeVersion=22033101&v65=WIFI&v61=disable&a.&action=trkAppButtonClick&OSVersion=iOS%2012.5.5&CarrierName=%28null%29&DeviceName=iPhone7%2C2&AppID=CTPocket%209.4.0%20%284%29&RunMode=Application&Resolution=750x1334&TimeSinceLaunch=2537&.a&lunchtype=aut_lunch&prePageAction=hit_event&.c&pev2=AMACTION%3AtrkAppButtonClick&pageName=CTPocket%2F4&ce=UTF-8&aid=540B88F2280D4599-146C532D0B076319&pe=lnk_o&cp=foreground]搜寻登录的账号13245678901后,发现日志里有登录的body信息,在setHTTPBody的js代码里打印堆栈: {  onEnter(log, args, state) {      var arg2 = new ObjC.Object(args[2])      log(`-[NSMutableURLRequest setHTTPBody:${arg2.bytes().readUtf8String()}]`);      log('NSMutableURLRequest setHTTPBody called from:\n' +              Thread.backtrace(this.context, Backtracer.ACCURATE)              .map(DebugSymbol.fromAddress).join('\n') + '\n');  },  onLeave(log, retval, state) {  }}获取到的堆栈信息如下: CTPocket!-[AFJSONRequestSerializer requestBySerializingRequest:withParameters:error:]0x10397ae50 CTPocket!-[AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:]0x10394edac CTPocket!-[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:]0x10394e378 CTPocket!-[AFHTTPSessionManager POST:parameters:headers:progress:success:failure:]0x101b8fae8 CTPocket!-[ESHttpSessionManager postWithHost:urlString:parameters:success:failure:]0x1015f91c8 CTPocket!-[ESNetworkingManager postWithURLString:parameters:modifiParamsBlock:success:failure:]0x100c14da4 CTPocket!-[ESLoginService loginWithPhoneNbr:type:code:isChinatelecom:slidingTime:percentage:success:failure:]0x101f85f58 CTPocket!-[ESBindLoginViewController phoneLoginWithPhoneNbr:type:code:slidingTime:percentage:isChinatelecom:isBind:failureBlock:]0x101f6a060 CTPocket!-[ESBindLoginViewController phoneLoginViewController:inputView:didSliderWithSlidingTime:Percentage:phoneNbr:passwd:loginType:isChinatelecom:isBind:failureBlock:]0x102ccb964 CTPocket!-[ESLoginViewController phoneLoginView:inputView:didSliderWithSlidingTime:Percentage:phoneNbr:passwd:loginType:isChinatelecom:isBind:]0x101261728 CTPocket!-[ESPhoneLoginView passwordInputView:sliderWithSlidingTime:Percentage:phoneNbr:passwd:]0x101e73d10 CTPocket!-[PasswordInputView commitBtnAction:]0x1e7091300 UIKitCore!-[UIApplication sendAction:to:from:forEvent:]0x10400a288 CTPocket!-[UIApplication(AutoTrack) sa_sendAction:to:from:forEvent:]0x1e6b3a424 UIKitCore!-[UIControl sendAction:to:forEvent:]0x1e6b3a744 UIKitCore!-[UIControl _sendActionsForEvents:withEvent:]接下来咱们应用frida-trace工具,对以上调用栈进行一一跟踪并打印入参,最终确定loginAuthCipherAsymmertric参数在[ESLoginService loginWithPhoneNbr:type:code:isChinatelecom:slidingTime:percentage:success:failure:]办法里生成的,关上IDA Pro并找到该办法,代码如下: __cdecl `-ESLoginService loginWithPhoneNbr:type:code:isChinatelecom:slidingTime:percentage:success:failure:{  id v10; // x19  id v11; // x20  id v12; // x25  id v13; // x21  ESLoginService v14; // x24  __int64 v15; // x1  __int64 v16; // x1  __int64 v17; // x1  __int64 v18; // x1  __int64 v19; // x1  __int64 v20; // x1  void v21; // x0  __int64 v22; // x25  void v23; // x0  unsigned int v24; // off  signed int v25; // w8   v10 = a8;  v11 = a7;  v12 = a6;  v13 = a5;  v14 = self;  objc_retain(a3, a2);  objc_retain(a9, v15);  objc_retain(a10, v16);  objc_retain(v10, v17);  objc_retain(v11, v18);  objc_retain(v12, v19);  objc_retain(v13, v20);  v21 = objc_msgSend(&OBJC_CLASS___NSDate, "date");  v22 = objc_retainAutoreleasedReturnValue(v21);  -ESLoginService setRequestDate:;  objc_release(v22);  v23 = (void )((__int64 (__fastcall )(void ))((char )off_105153068 + 92708870))(&OBJC_CLASS___NSDateFormatter);  objc_msgSend(v23, "init");  v24 = __ldar((unsigned int )&dword_10577A424);  if ( (unsigned int)&dword_10577A424 )    v25 = 7;  else    v25 = 34;  JUMPOUT(__CS__, (char )(&off_105153070 + v25) - dword_1051531F0[v25]);} ...

September 5, 2022 · 2 min · jiezi

关于ios:iOS如何实现验证码登录丨MobTech

开发工具:Xcode集成形式:手动导入SDK或者Pod集成SDK版本反对:SDK反对Xcode 9.1.0, iOS8.0+及以上版本展现效果图 编写代码在我的项目中创立登录页面,编写代码 #import "ViewController.h"#import <SMS_SDK/SMSSDK.h>@interface ViewController ()<UITextFieldDelegate>{ NSInteger _count;}@property (nonatomic,strong)UITextField *phNumTF;@property (nonatomic,strong)UITextField *codeTF;@property (nonatomic,strong)UIButton *getCodeButton;@property (nonatomic,strong)UIButton *loginButton;@property (nonatomic,strong)NSTimer *timer;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; UILabel *titleLabel = [[UILabel alloc]init]; titleLabel.frame = CGRectMake((self.view.frame.size.width-100)/2, 100, 100, 30); titleLabel.text = @"登录"; titleLabel.textAlignment = NSTextAlignmentCenter; titleLabel.font = [UIFont systemFontOfSize:16]; titleLabel.textColor = [UIColor blackColor]; [self.view addSubview:titleLabel]; UILabel *phNumLabel = [[UILabel alloc]init]; phNumLabel.frame = CGRectMake(50, titleLabel.frame.origin.y+200, 70, 30); phNumLabel.text = @"手机号码"; phNumLabel.font = [UIFont systemFontOfSize:16]; phNumLabel.textColor = [UIColor blackColor]; [self.view addSubview:phNumLabel]; self.phNumTF = [[UITextField alloc]initWithFrame:CGRectMake(130, phNumLabel.center.y-25, self.view.frame.size.width - 150, 50)]; self.phNumTF.placeholder = @"请输出手机号码"; self.phNumTF.textColor = [UIColor blackColor]; self.phNumTF.font = [UIFont systemFontOfSize:18]; [self.view addSubview:self.phNumTF]; UILabel *codeLabel = [[UILabel alloc]init]; codeLabel.frame = CGRectMake(50, phNumLabel.frame.origin.y+50, 50, 30); codeLabel.text = @"验证码"; codeLabel.font = [UIFont systemFontOfSize:16]; codeLabel.textColor = [UIColor blackColor]; [self.view addSubview:codeLabel]; self.codeTF = [[UITextField alloc]initWithFrame:CGRectMake(self.phNumTF.frame.origin.x, codeLabel.center.y-25, self.view.frame.size.width - 220, 50)]; self.codeTF.placeholder = @"请输出的短信验证码"; self.codeTF.textColor = [UIColor blackColor]; self.codeTF.font = [UIFont systemFontOfSize:18]; [self.view addSubview:self.codeTF]; self.getCodeButton = [UIButton buttonWithType:UIButtonTypeCustom]; self.getCodeButton.frame = CGRectMake(self.codeTF.frame.origin.y-30, self.codeTF.center.y - 15, 70, 30); [self.getCodeButton setTitle:@"获取验证码" forState:UIControlStateNormal]; [self.getCodeButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; self.getCodeButton.titleLabel.font = [UIFont systemFontOfSize:13]; [self.getCodeButton addTarget:self action:@selector(getCodeButtonClick) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:self.getCodeButton]; self.loginButton = [UIButton buttonWithType:UIButtonTypeCustom]; self.loginButton.frame = CGRectMake(80, self.codeTF.frame.origin.y+200, self.view.frame.size.width - 160, 50); self.loginButton.backgroundColor = [UIColor blueColor]; [self.loginButton setTitle:@"登录" forState:UIControlStateNormal]; self.loginButton.titleLabel.font = [UIFont systemFontOfSize:18]; [self.loginButton addTarget:self action:@selector(loginButtonClick) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:self.loginButton];}//获取短信验证码- (void)getCodeButtonClick{ self.getCodeButton.enabled =NO; _count = 120; [self.getCodeButton setTitle:@"120s后从新发送" forState:UIControlStateNormal]; self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];}//定时器-(void)timerFired:(NSTimer *)timer{ if (_count !=1) { _count -=1; [self.getCodeButton setTitle:[NSString stringWithFormat:@"%lds后从新发送",_count] forState:UIControlStateNormal]; //获取短信验证码 [SMSSDK getVerificationCodeByMethod:SMSGetCodeMethodSMS phoneNumber:self.phNumTF.text zone:@"86" template:@"" result:^(NSError *error) { if (!error) { // 申请胜利 } else { // error } }]; } else { [timer invalidate]; self.getCodeButton.enabled = YES; [self.getCodeButton setTitle:@"从新发送" forState:UIControlStateNormal]; }}//登录- (void)loginButtonClick{ //提交短信验证码 [SMSSDK commitVerificationCode:self.codeTF.text phoneNumber:self.phNumTF.text zone:@"86"result:^(NSError *error) { if (!error) { // 验证胜利 } else { // error } }];}@end至此,您已实现了短信验证码登录性能,欢快的游玩吧。 ...

September 1, 2022 · 2 min · jiezi

关于ios:MobTech-SMSSDK-iOS端快速集成指南

开发工具:Xcode集成形式:手动导入SDK或者Pod集成SDK版本反对:SDK反对Xcode 9.1.0, iOS8.0+及以上版本集成前筹备注册账号应用SMSSDK之前,您须要在MobTech官网注册开发者账号,增加利用并获取Mob提供的AppKey和AppSecret,详情能够点击查看注册流程 SMSSDK流程图 增加配置下载SDK导入我的项目(1)手动下载SDK引入点击 链接 下载最新版SDK,解压后失去以下文件构造: 将下图中红色框标记的文件夹(蕴含MOBFoundation.framework 和 SMS_SDK.framework)拖入到工程中 确认勾选,点击finish实现导入 (2)CocoaPods形式引入通过 CocoaPods进行装置,只需在 Podfile文件中增加:pod 'mob_smssdk'增加之后执行 pod install / pod update 命令即可。 增加依赖库必要: libz.tbdlibicucore.tbdMessageUI.frameworkJavaScriptCore.frameworklibc++.tbd留神:在XCode7下面运行报错的话,还须要减少这几个依赖库 SystemConfiguration.frameworkCoreTelephony.frameworkAdSupport.framework接口调用回传用户隐衷受权后果(uploadPrivacyPermissionStatus)为保障您的App在集成MobSDK之后可能满足工信部相干合规要求,您应确保App装置首次冷启动且获得用户浏览您《隐衷政策》受权之后,调用Mob提交到的隐衷协定回传函数uploadPrivacyPermissionStatus回传隐衷协定受权后果。反之,如果用户不批准您App《隐衷政策》受权,则不能调用uploadPrivacyPermissionStatus回传隐衷协定受权后果。相干隐衷申明请参考这个链接合规指南 /** 上传隐衷协定受权状态 @param isAgree 是否批准(用户受权后的后果) @param OnResult 执行回调后果,可为nil (留神业务逻辑不要依赖于这个success后果,倡议业务逻辑在调用这个接口之后来写) */+ (void)uploadPrivacyPermissionStatus:(BOOL)isAgree onResult:(void (^_Nullable)(BOOL success))handler;示例代码 #import <MOBFoundation/MobSDK+Privacy.h>[MobSDK uploadPrivacyPermissionStatus:YES onResult:^(BOOL success) {}];申请短信验证码(getVerificationCodeByMethod) /** * @from v3.1.0 * @brief 获取验证码(Get verification code) * * @param method 获取验证码的办法(The method of getting verificationCode) * @param phoneNumber 电话号码(The phone number) * @param zone 区域号,不要加"+"号(Area code) * @param tmpCode 模板id(template id) * @param result 申请后果回调(Results of the request) */+ (void) getVerificationCodeByMethod:(SMSGetCodeMethod)method phoneNumber:(NSString *)phoneNumber zone:(NSString *)zone template:(NSString *)tmpCode result:(SMSGetCodeResultHandler)result;示例代码 ...

September 1, 2022 · 1 min · jiezi

关于ios:MobTech-SMSSDK-iOS端-API

回传用户隐衷受权后果(uploadPrivacyPermissionStatus)/** 上传隐衷协定受权状态 @param isAgree 是否批准(用户受权后的后果) @param OnResult 执行回调后果,可为nil (留神业务逻辑不要依赖于这个success后果,倡议业务逻辑在调用这个接口之后来写) */+ (void)uploadPrivacyPermissionStatus:(BOOL)isAgree onResult:(void (^_Nullable)(BOOL success))handler;示例代码 #import <MOBFoundation/MobSDK+Privacy.h>[MobSDK uploadPrivacyPermissionStatus:YES onResult:^(BOOL success) {}];申请短信验证码(getVerificationCodeByMethod)/** * @from v3.1.0 * @brief 获取验证码(Get verification code) * * @param method 获取验证码的办法(枚举值:SMSGetCodeMethodSMS 文本短信形式 SMSGetCodeMethodVoice 语音验证码) * @param phoneNumber 电话号码(The phone number) * @param zone 区域号,不要加"+"号(Area code) * @param tmpCode 模板id(template id) * @param result 申请后果回调(Results of the request) */+ (void) getVerificationCodeByMethod:(SMSGetCodeMethod)method phoneNumber:(NSString *)phoneNumber zone:(NSString *)zone template:(NSString *)tmpCode result:(SMSGetCodeResultHandler)result;示例代码 ...

September 1, 2022 · 2 min · jiezi

关于ios:No-accounts-with-App-Store-Connect-access-have-been-found

最近打包的时候须要了这个问题。参考了网上的做法如这个链接:https://blog.csdn.net/BUG_del... 理论在第一步重启xcode,曾经解决了问题

August 31, 2022 · 1 min · jiezi

关于ios:wkwebview横屏播放后状态栏异常问题解决

WkWebview横屏全屏播放当前,回到竖屏状态会导致状态栏异样。与这个问题相似:https://stackoverflow.com/que... 解决方案也是如此。写下oc的解决办法: //横屏状态下暗藏状态栏,保障视频能够全屏播放- (BOOL)prefersStatusBarHidden { return UIApplication.sharedApplication.statusBarOrientation == UIInterfaceOrientationLandscapeLeft || UIApplication.sharedApplication.statusBarOrientation == UIInterfaceOrientationLandscapeRight;}//放到viewDidLoad办法外面监听屏幕的变动[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];//刷新statusbar的暗藏状态,当屏幕地位发生变化的时候- (void)handleDeviceOrientationDidChange { [self setNeedsStatusBarAppearanceUpdate];}

August 30, 2022 · 1 min · jiezi

关于ios:云音乐iOS端网络图片下载优化实践

图片来自:https://unsplash.com 本文作者: lgq背景图片展现,在各大APP中不可或缺,家喻户晓云音乐是一款带有社交属性的音乐软件,那么在任何社交场景,都会有展现图片的诉求,并且经常会有重图片场景,比方一个云音乐中Mlog的Feed流场景全都是图片,或者就是Mlog中的图集,都须要展现大量的图片,要是图片无奈及时的展现进去,不能及时的被用户生产,那么会造成用户浏览信息不顺畅,导致用户的散失,因而优化图片下载火烧眉毛。 现有图片下载技术这里简略理解下云音乐APP中接入的图片资源服务,它能够通过拼接参数,在远端进行裁剪,品质压缩从而下载到不同的图片。更多信息参考 影响图片下载的因素图片大小网络状况本地缓存cdn缓存综上所述,如何进步图片的下载速度能够从下面几点开始优化。 优化形式网络优化传统 HTTP1.0 的架构下没法多路复用,采纳 HTTP2.0 的形式,申请同一ip域名的资源能够从节俭大量建连及传输工夫。除此之外笔者在做音视频场景较重的页面时,发现音视频流媒体的数据有时候会抢占大量带宽,导致图片下载十分的慢,这时须要对音视频场景资源下载做适当的管制,如限流等操作,具体看业务优先级。如音视频场景应用socket下载时能够适当调中recv buffer 大小。图片大小优化格局优化这是最容易想的到的也是最无效的,如果失常应用jpg,png等惯例图片,那图片的大小会是比拟大的,目前咱们的nos服务反对指定类型,将图片转成特定的格局,所以咱们这里应用webp,从而缩小图片的大小。(只须要在申请参数中拼接类型为webp即可)那除此之外呢,咱们还能够做一些什么? 按需裁剪比方一个 100 100 的控件,3 倍屏的状况下,咱们只须要下载 300 300 的图就能够了,如果图片超过个尺寸,咱们去下载那么大的也没有意义。所以依据控件大小,能够决定咱们下的图片大小,从而减小咱们所需下载的图片。压缩品质比方要求没有那么高的场景咱们只须要品质为 80 的图就能够了。思考以上几项做完,咱们能够发现速度至多晋升 30%,然而是不是能够做的更多,或者这个计划有什么纰漏? 取证为此咱们简略的拉取了一下后盾数据。发现有以下问题: URL拼接的参数不同,导致无奈命中本地缓存,这样会有反复下载的问题,比方用户头像,用户头像再各个场景反复呈现,而且大小不一,会下载屡次这样会导致肯定的资源节约。同时因为链接参数各异 cdn命中度不高不同机型的UI尺寸大小可能不太统一,导致下载的片尺寸会不一样,机型品种越多,拼接的尺寸状况也越多,服务端须要反复裁剪。品质参数由下层业务自行决定,会导致不同端没有约定好,下载到各式各样的图片解决伎俩 URL 参数标准化所谓的标准化是标准大前端应用的参数拼接,分为程序标准化,参数值拟合。咱们晓得一个下载图片的URL链接http://path?imageView=1&enlarge=1&quality=80&thumbnail=80x80&type=webp。其中参数咱们按首字母排序,这样在参数要求统一的状况下,不会呈现反复申请。thumbnail 参数其实对应的是须要下载的图片大小,咱们做拟合(依据后端统计的到的数据),分成多档(档位能够配置),依照宽边对其等比例缩放,这样能够尽可能少的防止机型屏幕差一点点,呈现了其余size的case。quality也同样分级,分成多档(档位能够配置)。去重,参数可能多拼接,对冗余参数去反复本地大小图片重用简略了解是本地有大图,取小图的时候无需额定网络申请,间接本地裁剪。咱们优化了读取本地缓存的逻辑,在取缓存的时候,咱们会进行关联查找,找到可用的图片进行裁剪,间接返回。具体规定如下:不同裁剪参数能够转化,x,z裁剪参数能够转为y,y不能够转x,z。都能够转为雷同的裁剪参数。其中x(内缩略),y(裁剪缩略),z(外缩略)的含意在本篇文档中有,代表着不同的填充模式。品质高的图片能够复用为品质低的图片,品质低的图片不能够复用为品质高的图片iOS 代码实现说完了计划之后,咱们能够上代码了,这里是 iOS的实现计划: 首先咱们是基于SDWebImage进行肯定的封装,先简略理解下SDWebImage中大略的流程。 从图中咱们能够看出,下载图片次要是应用了imageLoader,查找缓存这里是用了imageCache,这两个都在manager中被治理 革新流程 咱们只须要在数据流转的最开始对URL进行Fix,同时在查找缓存的时候对图片减少额定查找即可。 URL FIX咱们给URL减少一个分类,对URL进行一个fix操作,计划就是用零碎提供的 NSURLComponts对齐进行操作,提取出他的参数,进行去重,标准化,同时咱们有一些历史起因,一些老的参数将其转为正确的格局,最初一步进行排序,fix流程就实现了。 - (NSURL *)demo_fixImageURL { NSURLComponts *componts = [NSURLComponts compontsWithURL:self resolvingAgainstBaseURL:YES]; NSMutableArray<NSURLQueryItem *> *queryItems = componts.queryItems.mutableCopy; ... 从URL取出 NSURLQueryItem 省略一些代码 if (qualityItem) { //quality 拟合, 将品质参数分为几档 NSString *defaultQualityStr = @"39,69,89"; //这里是伪代码,就是为了获取配置信息 NSArray<NSString *> *qualityLevel = CustomConfigQualityLevels; //固定 4档 if (qualityLevel.count == 3) { NSInteger quality = [qualityItem.value intValue]; NSString *fixQuality = @""; if (quality <= [[qualityLevel _objectAtIndex:0] intValue]) { fixQuality = [@(ImageQualityLevelLow) stringValue]; } else if (quality <= [[qualityLevel _objectAtIndex:1] intValue]) { fixQuality = [@(ImageQualityLevelMed) stringValue]; } else if (quality <= [[qualityLevel _objectAtIndex:2] intValue]) { fixQuality = [@(ImageQualityLevelHigh) stringValue]; } else { fixQuality = [@(ImageQualityLevelOrigin) stringValue]; } NSURLQueryItem *fixQualityItem = [[NSURLQueryItem alloc] initWithName:@"quality" value:fixQuality]; [queryItems removeObject:qualityItem]; [queryItems addObject:fixQualityItem]; } } if (sizeItem) { //size 依照宽边拟合 分为几档且 等比缩放 NSString *defaultSizeStr = @"30,60,90,120,180,256,315,512,720,1024"; //这里是伪代码 就是为了获取配置信息 NSArray<NSString *> *sizeLevels = CustomConfigSizeLevels; NSString *originSizeStr = sizeItem.value; CGSize originSize = CGSizeZero; NSString *separatedStr = nil; for (NSString *separated in @[@"x", @"z", @"y"]) { NSArray *sizeList = [originSizeStr compontsSeparatedByString:separated]; if (sizeList.count == 2) { originSize = CGSizeMake([sizeList[0] intValue], [sizeList[1] intValue]); separatedStr = separated; break; } } CGSize finalSize = CGSizeZero; if (!CGSizeEqualToSize(originSize, CGSizeZero)) { BOOL isW = originSize.width > originSize.height; NSInteger len = isW ? originSize.width : originSize.height; NSInteger requestSize = 0; for (NSString *sizeLevel in sizeLevels) { NSInteger sizeNumber = [sizeLevel integerValue]; if (sizeNumber >= len) { if (requestSize == 0) { requestSize = sizeNumber; } else { requestSize = MIN(requestSize, sizeNumber); } } } if (isW) { if (originSize.width != 0) { NSInteger h = (requestSize / (originSize.width * 1.f)) * originSize.height; finalSize = CGSizeMake(requestSize, floor(h)); } } else { if (originSize.height != 0) { NSInteger w = (requestSize / (originSize.height * 1.f)) * originSize.width; finalSize = CGSizeMake(w, floor(requestSize)); } } } if (!CGSizeEqualToSize(finalSize, CGSizeZero)) { NSString *fixSize = [NSString stringWithFormat:@"%ld%@%ld",(NSInteger)finalSize.width, separatedStr, (NSInteger)finalSize.height]; NSURLQueryItem *fixSizeItem = [[NSURLQueryItem alloc] initWithName:@"thumbnail" value:fixSize]; [queryItems removeObject:sizeItem]; [queryItems addObject:fixSizeItem]; } } //去反复 NSMutableArray<NSString *> *keys = @[].mutableCopy; queryItems = [queryItems bk_select:^BOOL(NSURLQueryItem *obj) { BOOL containsObject = [keys containsObject:obj.name]; [keys addObject:obj.name]; return !containsObject; }].mutableCopy; //首字母排序 queryItems = [queryItems sortedArrayUsingComparator:^NSComparisonResult(NSURLQueryItem *obj1, NSURLQueryItem *obj2) { return [obj1.name compare:obj2.name options:NSCaseInsensitiveSearch]; }].mutableCopy; //最终组合 componts.queryItems = queryItems.copy; NSURL *finalURL = componts.URL; return finalURL;}SDWebImageManager修复了URL之后,下一步要做什么,如何将修复后的URL传递上来呢?也能够从下面的SDWebImage流程中看出,所有的图片下载流程,离不开SDWebImageManager,所以咱们继承 SDWebImageManager,重写以下办法 ...

August 29, 2022 · 5 min · jiezi

关于ios:iOS逆向某交友App的xsign算法分析

浏览此文档的过程中遇到任何问题,请关注公众号【挪动端Android和iOS开发技术分享】或加QQ群【812546729】1.指标某交友软件的x-sign算法剖析。2.操作环境mac零碎frida-ios-dump:砸壳Charles:抓包已越狱iOS设施:脱壳及frida调试IDA Pro:动态剖析3.流程寻找切入点在账号密码登录页,点击登录,通过Charles抓包获取到关键词为x-sign,这也就是咱们的切入点:剖析过程应用frida-ios-dump的砸壳命令dump.py com.wemomo.momoappdemo1 砸壳获取到ipa文件,再应用IDA Pro编译ipa文件,而后搜寻搜寻字符串x-sign,后果如下: 查找该字符串的穿插援用,发现只有一处办法有应用:应用frida-trace的frida-trace -UF -m "-[TBSDKRequest setHTTPRequestHeader]"命令跟踪该函数,发现点击登录按钮,该办法并没有调用,阐明该x-sign并非抓包获取到的x-sign参数。既然x-sign在header里。那咱们再应用frida-trace -UF -m "-[NSMutableURLRequest setValue:forHTTPHeaderField:]"命令尝试跟踪设置header的函数,js代码如下:{onEnter(log, args, state) {log('--------------- start ---------------')log(-[NSMutableURLRequest setValue:${new ObjC.Object(args[2])} forHTTPHeaderField:${new ObjC.Object(args[3])}]);log('NSMutableURLRequest setValue:forHTTPHeaderField:]\n' +  Thread.backtrace(this.context, Backtracer.ACCURATE) .map(DebugSymbol.fromAddress).join('\n') + '\n');log('--------------- end ---------------')},onLeave(log, retval, state) {}}点击登录后,获取到要害信息如下:witchan@witchandeMacBook-Air ~ % frida-trace -UF -m "-[NSMutableURLRequest setValue:forHTTPHeaderField:]"Instrumenting...-[NSMutableURLRequest setValue:forHTTPHeaderField:]: Loaded handler at "/Users/witchan/__handlers__/NSMutableURLRequest/setValue_forHTTPHeaderField_.js"Started tracing 1 function. Press Ctrl+C to stop.           / TID 0x303 /5679 ms  --------------- start ---------------5679 ms  -[NSMutableURLRequest setValue:TpBMMTGM5Lcu+FOochRUPZgo8Pg= forHTTPHeaderField:X-SIGN]5679 ms NSMutableURLRequest setValue:forHTTPHeaderField:]0x101893dcc MomoChat!-[NSMutableURLRequest(CustomHeader) injectParaToHeader:]0x105cdebcc MomoChat!-[MDRequestSerializer requestWithMethod:URLString:parameters:error:]0x1033ceb80 MomoChat!-[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:]0x1033ce294 MomoChat!-[AFHTTPSessionManager POST:parameters:headers:progress:success:failure:]0x105cdc138 MomoChat!-[MDHTTPSessionManager requestWithApiParam:success:failure:]0x105cbd4b4 MomoChat!+[MDApiBase postRequestWithApiParam:]0x104e99904 MomoChat!-[MDLoginService accountLoginWithAccount:params:completion:]0x104e80fd0 MomoChat!-[MDAccountLoginManager requestAccountLoginWithAccount:params:completion:]0x104eb2958 MomoChat!-[MDRegLoginAccountViewController didClickCompleteButton:]0x216999300 UIKitCore!-[UIApplication sendAction:to:from:forEvent:]0x216442424 UIKitCore!-[UIControl sendAction:to:forEvent:]0x216442744 UIKitCore!-[UIControl _sendActionsForEvents:withEvent:]0x2164417b0 UIKitCore!-[UIControl touchesEnded:withEvent:]0x2165bb2d0 UIKitCore!_UIGestureEnvironmentUpdate0x2165b93a8 UIKitCore!-[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:]0x2165b9188 UIKitCore!-[UIGestureEnvironment _updateForEvent:window:]5679 ms  --------------- end ---------------依据调用堆栈可知设置x-sign的函数在[NSMutableURLRequest injectParaToHeader:],持续trace该函数frida-trace -UF -m "-[NSMutableURLRequest injectParaToHeader:]",js代码如下:{ onEnter(log, args, state) {   log(-[NSMutableURLRequest injectParaToHeader:]); var obj = new ObjC.Object(args[2]) var ivar = obj.$ivars for (var key in ivar) { log("k:" + key + " v:" + ivar[key]); } }, onLeave(log, retval, state) { }}失去日志如下: 2016 ms -[NSMutableURLRequest injectParaToHeader:] 2016 ms k:isa v:MDApiParam 2016 ms k:_compressed v:true 2016 ms k:_loggedIn v:true 2016 ms k:_licienceKey v:63c92d0c 2016 ms k:_paraDic v:{\nBc4grei+NtA8CMpMOGw=";G90EcFCPigXsWIIvM++Z4Uzf033xcRe1544/byyAWPRDZJJn0TCpp/UgevDQVJ   "code_version" = 2;   "map_id" = 782054678088;\nbkMIYHkZkBGwC3Ix4q5ksZrxiRD/Xq3v2EGGb7Asv5mByy7ZQ6pG1TYZ";9bcNyVCkUsYGBlUTMc/8ZoFy6ClL} 2016 ms k:_backupDic v:{   "_idfa_" = "21D2A6AF-58D5-4E0A-ABBA-FC5972DAE0BD";   "_net_" = wifi;   "_uid_" = 3d6777a2d9e59e5da0cf8b6b75e0f1fb;   account = 13333333333;   bindSource = "bind_source_new_login";   ct = "1661094132.711969";   lat = 0;   lng = 0;   password = e3ceb5881a0a1fdaad01296d7554868d;   rqid = e3f4be75;   uid = 3d6777a2d9e59e5da0cf8b6b75e0f1fb;} 2016 ms k:_tokenString v:null 2016 ms k:_currentLV v:1 2016 ms k:_decodeFailedCount v:0 2016 ms k:_signString v:QV+H6sFy/QHCfrFndOKn/IhfnIg= 2016 ms k:_isThirdRequest v:false 2016 ms k:_delegate v:null 2016 ms k:_successSelector v:0x0 2016 ms k:_failSelector v:0x0 2016 ms k:_errorSelector v:0x0 2016 ms k:_identifier v:null 2016 ms k:_headers v:null 2016 ms k:_cookie v:null 2016 ms k:_userInfo v:null 2016 ms k:_timeout v:15 2016 ms k:_requestType v:3 2016 ms k:_urlString v:https://api.immomo.com/api/v2... 2016 ms k:_urlHost v:api.immomo.com 2016 ms k:_uploadData v:null 2016 ms k:_otherPara v:null 2016 ms k:_state v:0 2016 ms k:_successCallbackBlock v:[object Object] 2016 ms k:_failCallbackBlock v:[object Object] 2016 ms k:_errorCallbackBlock v:[object Object] 2069 ms -[NSMutableURLRequest injectParaToHeader:] 2069 ms k:isa v:MDApiParam 2069 ms k:_compressed v:false 2069 ms k:_loggedIn v:true 2069 ms k:_licienceKey v:null 2069 ms k:_paraDic v:{   "_idfa_" = "21D2A6AF-58D5-4E0A-ABBA-FC5972DAE0BD";   "_net_" = wifi;   "_uid_" = 3d6777a2d9e59e5da0cf8b6b75e0f1fb;   "click_sign" = "click_account_login_button";   type = "login_register_click";} 2069 ms k:_backupDic v:null 2069 ms k:_tokenString v:null 2069 ms k:_currentLV v:0 2069 ms k:_decodeFailedCount v:0 2069 ms k:_signString v:null 2069 ms k:_isThirdRequest v:false 2069 ms k:_delegate v:null 2069 ms k:_successSelector v:0x0 2069 ms k:_failSelector v:0x0 2069 ms k:_errorSelector v:0x0 2069 ms k:_identifier v:null 2069 ms k:_headers v:null 2069 ms k:_cookie v:null 2069 ms k:_userInfo v:null 2069 ms k:_timeout v:15 2069 ms k:_requestType v:1 2069 ms k:_urlString v:https://api.immomo.com/v1/log... 2069 ms k:_urlHost v:api.immomo.com 2069 ms k:_uploadData v:null 2069 ms k:_otherPara v:null 2069 ms k:_state v:0 2069 ms k:_successCallbackBlock v:null 2069 ms k:_failCallbackBlock v:null 2069 ms k:_errorCallbackBlock v:null依据申请头的x-sign值发现,x-sign参数在MDApiParam类的_signString属性里,那咱们跟踪MDApiParam类的setSignString:办法,frida-trace -UF -m "-[MDApiParam setSignString:]",后果跟踪失败。那就阐明该办法在MDApiParam的父类,那咱们调整trace命令为frida-trace -UF -m "-[* setSignString:]",js代码如下:{onEnter(log, args, state) { log(-[MDApiBaseParam setSignString:${new ObjC.Object(args[2])}]);   log('MDApiBaseParam setSignString:]\n' +       Thread.backtrace(this.context, Backtracer.ACCURATE)       .map(DebugSymbol.fromAddress).join('\n') + '\n');   log('--------------- end ---------------')},onLeave(log, retval, state) {}}跟踪日志如下:2838 ms -[MDApiBaseParam setSignString:3XEvF8ZcUY1v7bknbQYWKsrajvQ=]2838 ms MDApiBaseParam setSignString:]0x1018a6f3c MomoChat!+[MDPrivateKeyGenerator handleRegisterPara:withGenerator:operatorItem:userAgentData:]0x105cc6ec0 MomoChat!-[MDAPIOperatorLayer statusOfSendingRequestPara:]0x105cde7f0 MomoChat!-[MDRequestSerializer requestWithMethod:URLString:parameters:error:]0x1033ceb80 MomoChat!-[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:]0x1033ce294 MomoChat!-[AFHTTPSessionManager POST:parameters:headers:progress:success:failure:]0x105cdc138 MomoChat!-[MDHTTPSessionManager requestWithApiParam:success:failure:]0x105cbd4b4 MomoChat!+[MDApiBase postRequestWithApiParam:]0x104e99904 MomoChat!-[MDLoginService accountLoginWithAccount:params:completion:]0x104e80fd0 MomoChat!-[MDAccountLoginManager requestAccountLoginWithAccount:params:completion:]0x104eb2958 MomoChat!-[MDRegLoginAccountViewController didClickCompleteButton:]0x216999300 UIKitCore!-[UIApplication sendAction:to:from:forEvent:]0x216442424 UIKitCore!-[UIControl sendAction:to:forEvent:]0x216442744 UIKitCore!-[UIControl _sendActionsForEvents:withEvent:]0x2164417b0 UIKitCore!-[UIControl touchesEnded:withEvent:]0x2165bb2d0 UIKitCore!_UIGestureEnvironmentUpdate0x2165b93a8 UIKitCore!-[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:]2838 ms --------------- end ---------------依据调用堆栈,在IDA Pro查看[MDPrivateKeyGenerator handleRegisterPara:withGenerator:operatorItem:userAgentData:]函数,该函数有应用ollvm混同,不过,通过关键词搜寻,发现指标函数:发现生成sign的函数为MDPrivateKeyGenerator类的signStringForEncryptedData:userAgentData:withTDKey:办法。frida-trace -UF -m "[MDPrivateKeyGenerator signStringForEncryptedData:userAgentData:withTDKey:]" -m "[MDPrivateEncryptor encryptData:withPassword:error:]" -m "[NSJSONSerialization dataWithJSONObject:options:error:]"该办法,对应js代码如下:[MDPrivateKeyGenerator signStringForEncryptedData:userAgentData:withTDKey:]{onEnter(log, args, state) { var obj = new ObjC.Object(args[2]); var ua = new ObjC.Object(args[3]); log(+[MDPrivateKeyGenerator signStringForEncryptedData:${obj} userAgentData:${ua.bytes().readUtf8String(ua.length())} withTDKey:${new ObjC.Object(args[4])}]); log('MDPrivateKeyGenerator signStringForEncryptedData from:\n' +       Thread.backtrace(this.context, Backtracer.ACCURATE)       .map(DebugSymbol.fromAddress).join('\n') + '\n');},onLeave(log, retval, state) { log(+[MDPrivateKeyGenerator signStringForEncryptedData:userAgentData:withTDKey:]=${new ObjC.Object(retval)}=);}}[MDPrivateEncryptor encryptData:withPassword:error:]{onEnter(log, args, state) { var obj = new ObjC.Object(args[2]); log(+[MDPrivateEncryptor encryptData:${obj} withPassword:${args[3]} error:${args[4]}]);},onLeave(log, retval, state) { var obj = new ObjC.Object(retval); log(+[MDPrivateEncryptor encryptData:withPassword:error:]=${obj}=);}}[NSJSONSerialization dataWithJSONObject:options:error:]{onEnter(log, args, state) { log(+[NSJSONSerialization dataWithJSONObject:${new ObjC.Object(args[2])} options:${args[3]} error:${args[4]}]);},onLeave(log, retval, state) { var obj = new ObjC.Object(retval); log(+[NSJSONSerialization dataWithJSONObject:options:error:]=${obj}=);}}要害日志如下:+[NSJSONSerialization dataWithJSONObject:{ "_idfa_" = "21D2A6AF-58D5-4E0A-ABBA-FC5972DAE0BD"; "_net_" = wifi; "_uid_" = 3d6777a2d9e59e5da0cf8b6b75e0f1fb; account = 13333333333; bindSource = "bind_source_new_login"; ct = "1661097991.706133"; lat = 0; lng = 0; password = e3ceb5881a0a1fdaad01296d7554868d; rqid = b0a993ba; uid = 3d6777a2d9e59e5da0cf8b6b75e0f1fb;} options:0x0 error:0x0]+[NSJSONSerialization dataWithJSONObject:options:error:]=<7b227569 64223a22 33643637 37376132 64396535 39653564 61306366 38623662 37356530 66316662 222c225f 6e65745f 223a2277 69666922 2c226374 223a2231 36363130 39373939 312e3730 36313333 222c225f 69646661 5f223a22 32314432 41364146 2d353844 352d3445 30412d41 4242412d 46433539 37324441 45304244 222c226c 6174223a 2230222c 22706173 73776f72 64223a22 65336365 62353838 31613061 31666461 61643031 32393664 37353534 38363864 222c2262 696e6453 6f757263 65223a22 62696e64 5f736f75 7263655f 6e65775f 6c6f6769 6e222c22 72716964 223a2262 30613939 33626122 2c226163 636f756e 74223a22 31333333 33333333 33333322 2c226c6e 67223a22 30222c22 5f756964 5f223a22 33643637 37376132 64396535 39653564 61306366 38623662 37356530 66316662 227d>=+[MDPrivateEncryptor encryptData:<7b227569 64223a22 33643637 37376132 64396535 39653564 61306366 38623662 37356530 66316662 222c225f 6e65745f 223a2277 69666922 2c226374 223a2231 36363130 39373939 312e3730 36313333 222c225f 69646661 5f223a22 32314432 41364146 2d353844 352d3445 30412d41 4242412d 46433539 37324441 45304244 222c226c 6174223a 2230222c 22706173 73776f72 64223a22 65336365 62353838 31613061 31666461 61643031 32393664 37353534 38363864 222c2262 696e6453 6f757263 65223a22 62696e64 5f736f75 7263655f 6e65775f 6c6f6769 6e222c22 72716964 223a2262 30613939 33626122 2c226163 636f756e 74223a22 31333333 33333333 33333322 2c226c6e 67223a22 30222c22 5f756964 5f223a22 33643637 37376132 64396535 39653564 61306366 38623662 37356530 66316662 227d> withPassword:0x282806bc0 error:0x0]+[MDPrivateEncryptor encryptData:withPassword:error:]=<020350f1 d8c4006a 2daffbca efd85d33 0b76f031 c23d38f6 7c8a1ef9 ed054baa d07aeba0 fb780f76 6822ac1b a68c9254 3cc58d5e 8707e40b 8f68ff0c fbcdea46 db6cc822 1c1e7e84 332805d5 88edcb1a 182a1db7 4c0e4568 75ee7859 b5f4af82 67ec6662 03e41725 740412e2 655d04a9 fc9321fe 5220ed14 076d2a2d 8d840686 0107810f 886cd438 eec7b0ce 4f244ecc acafb5ad 285bec58 e714962d 9e4e5fba 75ac82cd cf23c69e 862f0833 9e337628 c3b79aa3 2571ff8f 4b3f44c9 52357277 5beb8dce f1e9cc9a 6e763b6e eb2ae747 d00d571b 3d668e09 f37dec21 3aaf6bd6 b8714b98 b1b1513c ef5f080c fc07b17b a0cc5991 ac9e58d7 b1c14edb 084b1c0e 05ac1bb8 15b5efcb a64f1f86 035a1e84 b326a8bc 355093d6 dd8a12d8 96bbe3e0 9a252878 18cfc115 78507b3c 20baedf4 495c969b 4e433364 ceddf0a3 f759aab0 4402cfe9 4aa934>=+[MDPrivateKeyGenerator signStringForEncryptedData:<020350f1 d8c4006a 2daffbca efd85d33 0b76f031 c23d38f6 7c8a1ef9 ed054baa d07aeba0 fb780f76 6822ac1b a68c9254 3cc58d5e 8707e40b 8f68ff0c fbcdea46 db6cc822 1c1e7e84 332805d5 88edcb1a 182a1db7 4c0e4568 75ee7859 b5f4af82 67ec6662 03e41725 740412e2 655d04a9 fc9321fe 5220ed14 076d2a2d 8d840686 0107810f 886cd438 eec7b0ce 4f244ecc acafb5ad 285bec58 e714962d 9e4e5fba 75ac82cd cf23c69e 862f0833 9e337628 c3b79aa3 2571ff8f 4b3f44c9 52357277 5beb8dce f1e9cc9a 6e763b6e eb2ae747 d00d571b 3d668e09 f37dec21 3aaf6bd6 b8714b98 b1b1513c ef5f080c fc07b17b a0cc5991 ac9e58d7 b1c14edb 084b1c0e 05ac1bb8 15b5efcb a64f1f86 035a1e84 b326a8bc 355093d6 dd8a12d8 96bbe3e0 9a252878 18cfc115 78507b3c 20baedf4 495c969b 4e433364 ceddf0a3 f759aab0 4402cfe9 4aa934> userAgentData:MomoChat/9.2.6 ios/4268 (iPhone 6; iOS 12.5.5; zh_CN; iPhone7,2; S1) withTDKey:LZekgG6VHCbwKhzTeSHYx+BbJJOUJsggLZekgG6VHCbwKhzT]MDPrivateKeyGenerator signStringForEncryptedData from:0x1018a6f1c MomoChat!+[MDPrivateKeyGenerator handleRegisterPara:withGenerator:operatorItem:userAgentData:]0x105cc6ec0 MomoChat!-[MDAPIOperatorLayer statusOfSendingRequestPara:]0x105cde7f0 MomoChat!-[MDRequestSerializer requestWithMethod:URLString:parameters:error:]0x1033ceb80 MomoChat!-[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:]0x1033ce294 MomoChat!-[AFHTTPSessionManager POST:parameters:headers:progress:success:failure:]0x105cdc138 MomoChat!-[MDHTTPSessionManager requestWithApiParam:success:failure:]0x105cbd4b4 MomoChat!+[MDApiBase postRequestWithApiParam:]0x104e99904 MomoChat!-[MDLoginService accountLoginWithAccount:params:completion:]0x104e80fd0 MomoChat!-[MDAccountLoginManager requestAccountLoginWithAccount:params:completion:]0x104eb2958 MomoChat!-[MDRegLoginAccountViewController didClickCompleteButton:]0x216999300 UIKitCore!-[UIApplication sendAction:to:from:forEvent:]0x216442424 UIKitCore!-[UIControl sendAction:to:forEvent:]0x216442744 UIKitCore!-[UIControl _sendActionsForEvents:withEvent:]0x2164417b0 UIKitCore!-[UIControl touchesEnded:withEvent:]0x2165bb2d0 UIKitCore!_UIGestureEnvironmentUpdate0x2165b93a8 UIKitCore!-[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:]+[MDPrivateKeyGenerator signStringForEncryptedData:userAgentData:withTDKey:]=LbQ1kIg2MGf+5uXtUR4MguFYTIE==通过整顿得出:签名函数[MDPrivateKeyGenerator signStringForEncryptedData:userAgentData:withTDKey:]的入参别离为:EncryptedData:调用[MDPrivateEncryptor encryptData:withPassword:error:]生成,入参为:{ "_idfa_" = "21D2A6AF-58D5-4E0A-ABBA-FC5972DAE0BD"; "_net_" = wifi; "_uid_" = 3d6777a2d9e59e5da0cf8b6b75e0f1fb; account = 13333333333; bindSource = "bind_source_new_login"; ct = "1661097991.706133"; lat = 0; lng = 0; password = e3ceb5881a0a1fdaad01296d7554868d; rqid = b0a993ba; uid = 3d6777a2d9e59e5da0cf8b6b75e0f1fb;}userAgentData:MomoChat/9.2.6 ios/4268 (iPhone 6; iOS 12.5.5; zh_CN; iPhone7,2; S1)也就是申请头的user-agent字段TDKey:LZekgG6VHCbwKhzTeSHYx+BbJJOUJsggLZekgG6VHCbwKhzT函数[MDPrivateKeyGenerator signStringForEncryptedData:userAgentData:withTDKey:]被混同过了,抠出要害代码如下:id __cdecl +MDPrivateKeyGenerator signStringForEncryptedData:userAgentData:withTDKey:{ NSMutableData data = [[NSMutableData alloc] initWithData:ua]; [data appendData:inData]; return [MDPrivateKeyGenerator signDataForData: data withKey: key];}[MDPrivateKeyGenerator signDataForData:withKey:]依然被混同,持续抠出要害代码如下: case 1048019035: objc_retainAutorelease(data1); data_byte = objc_msgSend(data1, bytes, v26); v38 = (__int64 )v33; v22 = (__int64 )v33; ((_DWORD )v33 + 4) = 0; v22 = 0LL; v22[1] = 0LL; objc_retainAutorelease(key2); key_c = objc_msgSend(key2, UTF8String, v26); outData = (__int64 )v33; dataLength = (unsigned __int64)objc_msgSend(data1, length1, v26); v40 = (unsigned int)sub_101137F5C(data_byte, key_c, outData, dataLength) == 0; v6 = 1136488291; break; }持续进入sub_101137F5C函数:__int64 __fastcall sub_101137F5C(char a1, _QWORD a2, void a3, signed int length){ size_t v4; // x22 size_t v5; // x23 signed int v6; // w9 char v7; // x24 char v8; // x24 signed int v9; // w8 BOOL v11; // [xsp+4h] [xbp-7Ch] char inData; // [xsp+8h] [xbp-78h] _QWORD key; // [xsp+10h] [xbp-70h] void outData; // [xsp+18h] [xbp-68h] signed int v15; // [xsp+24h] [xbp-5Ch] bool v16; // [xsp+2Bh] [xbp-55h] unsigned int v17; // [xsp+2Ch] [xbp-54h] inData = a1; v11 = length < 1 || a1 == 0LL || a2 == 0LL || a3 == 0LL; v4 = length; v5 = length + 8; v6 = -982936543; key = a2; outData = a3; do { while ( 1 ) { while ( 1 ) { while ( 1 ) { while ( 1 ) { v9 = v6; if ( v6 <= -213277501 ) break; if ( v6 > 1153753992 ) { if ( v6 > 1967097480 ) { if ( v6 == 1967097481 ) { v7 = (char )malloc(v5); memcpy(v7, inData, v4); (_QWORD )&v7[v4] = key; sub_101137BEC((__int64)v7, (__int64)outData, v5); free(v7); goto LABEL_8; } if ( v6 == 1993019028 )LABEL_6: v6 = -1283420476; } else if ( v6 == 1153753993 ) { v6 = -1085362011; } else if ( v6 == 1602184948 ) {LABEL_8: v6 = -2054010553; } } else if ( v6 > 932805686 ) { if ( v6 == 932805687 ) { v6 = -776523138; v16 = v11; } else if ( v6 == 1133444574 ) { v15 = 0; v6 = -816491233; } } else { v6 = 1153753993; if ( v9 != -213277500 ) { v6 = v9; if ( v9 == 589407864 ) v6 = 1153753993; } } } if ( v6 <= -1072802235 ) break; if ( v6 > -816491234 ) { if ( v6 == -816491233 ) { v17 = v15; goto LABEL_6; } if ( v6 == -776523138 ) { if ( v16 ) v6 = -213277500; else v6 = 1602184948; } } else { v6 = 932805687; if ( v9 != -1072802234 ) { v6 = v9; if ( v9 == -982936543 ) v6 = 932805687; } } } if ( v6 <= -1283420477 ) break; if ( v6 == -1283420476 ) { v6 = -2014741442; } else if ( v6 == -1085362011 ) { v15 = -970; v6 = -816491233; } } if ( v6 != -2054010553 ) break; v8 = (char )malloc(v5); memcpy(v8, inData, v4); (_QWORD )&v8[v4] = key; sub_101137BEC((__int64)v8, (__int64)outData, v5); free(v8); v6 = 1133444574; } } while ( v6 != -2014741442 ); return v17;}发现该函数最终调用了sub_101137BEC函数,持续点进去:__int64 __fastcall sub_101137BEC(__int64 inData, __int64 outData, signed int length){ signed int v3; // w20 signed int v4; // w9 signed int v5; // w8 __int64 v7; // [xsp+0h] [xbp-70h] __int64 v8; // [xsp+8h] [xbp-68h] void v9; // [xsp+10h] [xbp-60h] bool v10; // [xsp+19h] [xbp-57h] bool v11; // [xsp+1Ah] [xbp-56h] bool v12; // [xsp+1Bh] [xbp-55h] unsigned int v13; // [xsp+1Ch] [xbp-54h] v7 = length; v10 = inData == 0; v4 = -1578351266; v8 = inData; v9 = (void )outData; v11 = length < 1; while ( 1 ) { while ( 1 ) { while ( 1 ) { while ( 1 ) { v5 = v4; if ( v4 > -472472763 ) break; if ( v4 > -1578351267 ) { if ( v4 > -1093978826 ) { v4 = -1307992632; if ( v5 != -1093978825 ) { v4 = v5; if ( v5 == -954022793 ) { v13 = v3; v4 = 682513349; } } } else if ( v4 == -1578351266 ) { if ( v10 || v11 ) v4 = -1093978825; else v4 = 1410854159; } else if ( v4 == -1307992632 ) { v4 = -472472762; } } else if ( v4 > -1972614761 ) { v4 = 566635925; if ( v5 != -1972614760 ) { v4 = v5; if ( v5 == -1711298395 ) { if ( v12 ) v4 = 841496535; else v4 = -1093978825; } } } else { v4 = 682513349; if ( v5 != -2077253293 ) { v4 = v5; if ( v5 == -1988385219 ) { v3 = 0; v4 = -954022793; } } } } if ( v4 > 589005999 ) break; if ( v4 > -69020687 ) { if ( v4 == -69020686 ) { sub_101C0BC50(v8, v7, v9); v4 = 589006000; } else if ( v4 == 566635925 ) { v4 = -1988385219; } } else if ( v4 == -472472762 ) { v3 = -978; v4 = -954022793; } else if ( v4 == -318483307 ) { v4 = -1307992632; } } if ( v4 > 841496534 ) break; if ( v4 == 589006000 ) { v12 = sub_101C0BC50(v8, v7, v9) != 0LL; v4 = -1711298395; } else if ( v4 == 682513349 ) { v4 = 1752038933; } } v4 = 566635925; if ( v5 != 841496535 ) { v4 = 589006000; if ( v5 != 1410854159 ) { v4 = v5; if ( v5 == 1752038933 ) break; } } } return v13;}发现该函数最终调用了sub_101C0BC50函数,再点进去:_DWORD __fastcall sub_101C0BC50(char inData, __int64 length, void outData){ __int64 length2; // x20 char inData2; // x21 _DWORD outData2; // x19 __int64 v7; // [xsp+0h] [xbp-90h] length2 = length; inData2 = inData; if ( outData ) outData2 = outData; else outData2 = &unk_10AC6B920; if ( !(unsigned int)sub_101C0BC08(&v7) ) return 0LL; sub_101C0AA00(&v7, inData2, length2); sub_101C0BB24(outData2, (unsigned int )&v7); sub_101C06228((__int64)&v7, 96LL); return outData2;}应用frida脚本打印sub_101C0BC50参数:js代码:var addr = 0x1C0BC50var baseAddr = Module.findBaseAddress('MomoChat')!;Interceptor.attach(baseAddr.add(addr), { onEnter: function(args) { console.log(addr.toString(16), "=begin tatget Addr===================================================================="); console.log(args[0].readCString()); console.log(args[1]); }, onLeave: function(retval) { var ret = ObjC.classes.NSData.dataWithBytes_length_(retval, 20); console.log("ret:", ret) console.log(addr.toString(16), "=end tatget Addr===================================================================="); }});日志如下:1c0bc50 =begin tatget Addr====================================================================���Ls�a' ��SRf�{�^�N$�6�����.�-�0x31ret: <e60f257b e0d30731 1767b31d 69877e97 2c4a6b68>1c0bc50 =end tatget Addr====================================================================1c0bc50 =begin tatget Addr====================================================================�%{0x4ret: <efc9e314 8643a3a5 6c68f597 d7786dc8 6e612142>1c0bc50 =end tatget Addr====================================================================1c0bc50 =begin tatget Addr===================================================================={"uid":"3d6777a2d9e59e5da0cf8b6b75e0f1fb","_net_":"wifi","ct":"1661534490.693195","_idfa_":"21D2A6AF-58D5-4E0A-ABBA-FC5972DAE0BD","lat":"0","password":"e3ceb5881a0a1fdaad01296d7554868d","bindSource":"bind_source_new_login","rqid":"de7161c2","account":"13333333333","lng":"0","_uid_":"3d6777a2d9e59e5da0cf8b6b75e0f1fb"}0x13eret: <305af756 afbb064b a1786925 657d15f9 2c45ae27>1c0bc50 =end tatget Addr====================================================================1c0bc50 =begin tatget Addr====================================================================0Z�V0x4ret: <cd712d01 ef9086a0 5df8ad81 45f84e75 3275f38f>1c0bc50 =end tatget Addr====================================================================1c0bc50 =begin tatget Addr====================================================================MomoChat/9.2.6 ios/4268 (iPhone 6; iOS 12.5.5; zh_CN; iPhone7,2; S1)0Z�V0x193ret: <7ab2461f 1b9fc68d 79469c19 2bb653a9 2ef706a6>1c0bc50 =end tatget Addr====================================================================1c0bc50 =begin tatget Addr====================================================================}��0x4ret: <97d96923 4d342ba2 d7767838 838707fd 6dc19ebb>1c0bc50 =end tatget Addr====================================================================<7ab2461f 1b9fc68d 79469c19 2bb653a9 2ef706a6>该数据转换成base64后,正是x-sign。后果sub_101C0BC50函数就是最终生成x-sign的中央,sub_101C0AA00函数对入参进行加工,sub_101C0BB24最终 生成x-sign参数。sub_101C0BB24函数的代码如下:signed __int64 __fastcall sub_101C0BB24(_DWORD a1, unsigned int inData){ unsigned int inData2; // x20 _DWORD outData; // x19 unsigned int v4; // x21 __int64 v5; // x8 signed __int64 v6; // x9 unsigned int v7; // w8 inData2 = inData; outData = a1; v4 = inData + 7; v5 = inData[23]; ((_BYTE )inData + v5 + 28) = -128; v6 = v5 + 1; if ( (unsigned int)v5 >= 0x38 ) { bzero((char )v4 + v6, 63 - v5); sub_101C0AB08(inData2, v4, 1LL); v6 = 0LL; } bzero((char )v4 + v6, 56 - v6); v7 = bswap32(inData2[5]); inData2[21] = bswap32(inData2[6]); inData2[22] = v7; sub_101C0AB08(inData2, v4, 1LL); inData2[23] = 0; sub_101C06228((__int64)v4, 64LL); outData = bswap32(*inData2); outData[1] = bswap32(inData2[1]); outData[2] = bswap32(inData2[2]); outData[3] = bswap32(inData2[3]); outData[4] = bswap32(inData2[4]); return 1LL;}这应该就是生成x-sign的最终函数,就先剖析到这吧。End浏览此文档的过程中遇到任何问题,请关注公众号【挪动端Android和iOS开发技术分享】或加QQ群【812546729】 ...

August 27, 2022 · 11 min · jiezi

关于ios:iOS端如何实现MobLink的场景还原功能

下载SDK1.登录官网2.点击这里 下载SDK勾选Moblink,点击下载 导入SDK1.将整个SDK文件,外面MobLinkPro.framework,MOBFoundation.framework拖到我的项目中,如下图: 勾选如下3项 增加依赖库 抉择我的项目Target - Build Phases - Link Binary With Libraries,而后抉择“+”进行增加零碎库:libsqlite3libz1.2.5libc++ Mob后盾与我的项目配置(1)如下,点击进去本人注册的利用,会看到MobLink上面的根底配置项,如下图: Universal Link (必填,咱们已生成能够间接用咱们生成的):强烈建议应用Mob主动生成的Universal Link。iOS 9.0及以上应用Universal Link能优化场景复原过程,提供更好的用户体验。抉择并应用咱们帮您生成的Universal Link并正确配置到您的我的项目中,将为您节俭大量工作和工夫。我的项目里配置如下: Team ID (必填):开发团队的ID,可在苹果开发者后盾查看: Bundle ID (必填):我的项目惟一标识。请务必与我的项目中保持一致。可见于我的项目Info.plist文件的Bundle identifierURL Scheme (必填):在后盾填写格局如:XXX:// (后面任意,前面必须要带://),请务必与我的项目中的配置保持一致,否则可能会导致无奈跳转利用,我的项目里配置不带://,如下图: 下载/疏导地址 (必填):利用在App Store的下载地址,或者是其余第三方托管地址,没有装置app会跳转到这里来下载app App Store下载地址 (选填):专业版无效,经典版有效,在这里配置了的话,会略过咱们的下载疏导界面,间接跳App Store下载 app利用宝下载链接 :安卓须要,iOS不须要填写无效工夫 :这个工夫是点开链接后开始计时的,超过这个时候后,点击"关上app"无奈胜利场景复原,倡议设置为60分钟,测试阶段可自行批改以查看成果,设置为0时不进行场景复原。 (2)路由配置(必须) 渠道标识:填写还原门路,如"/demo/a","/demo/b“等,这个填写的值须要与前端JS里传的path的值统一; iOS页面名称:填写跳转到app须要复原的控制器的名称,如果不填写无奈走客户端的场景还原的回调获取参数等 (3)配置ATS 1.在我的项目的info.plist中增加 App Transport Security Settings,类型为字典类型 2.给它增加一个Key:Allow Arbitrary Loads,类型为Boolean类型,值为YES; 初始化SDK在我的项目中的info.plist文件中增加键值对,键别离为 MOBAppKey 和 MOBAppSecret ,值为在之前在MobTech官网开发者后盾申请的appkey和appSecret(留神:配置后须要保留好,看下我的项目Info选项里是否存在 ) 场景接口调用在须要复原的控制器中实现UIViewController+MLSDKRestore的办法例如在MLDNewsDetailTableViewController.m是我须要复原的控制器,在外面增加 #import <MobLinkPro/MLSDKScene.h>#import <MobLinkPro/UIViewController+MLSDKRestore.h>@property (nonatomic, strong) MLSDKScene *scene;//实现带有场景参数的初始化办法,并依据场景参数还原该控制器:-(instancetype)initWithMobLinkScene:(MLSDKScene *)scene{ if (self = [super init]) { self.scene = scene; } return self;}获取MobId将其用于分享。在场景数据还原时MobLink会依据MobId还原出场景数据,并回调给用户进行特定的操作(留神:MobId不是必须要用的,比方应用的场景是从网页跳转到App里的时候所有参数齐全来源于网页上的时候,这时是不须要获取的MobId的,只须要在前端网页上js初始化的时候写上必要的参数就能够了。这个MobId实用于个别从App分享链接进来的时候有些参数是在App内指定的,比方分享者的id等等,此时就须要通过这个MobId来携带着客户端的参数到网页上转悠一圈,而后从网页跳转回App的时候又返回给App这样。) ...

August 26, 2022 · 1 min · jiezi

关于ios:ios15-tabbar去掉透明和上面黑线

if (@available(iOS 15.0, *)) { UITabBarAppearance *tabbarAppearance = [UITabBarAppearance new]; [tabbarAppearance configureWithDefaultBackground]; tabbarAppearance.backgroundColor = [UIColor whiteColor]; tabbarAppearance.shadowColor = [UIColor clearColor]; tabbarAppearance.backgroundImage = [UIImage new]; UITabBar.appearance.standardAppearance = tabbarAppearance; UITabBar.appearance.scrollEdgeAppearance = tabbarAppearance;}

August 26, 2022 · 1 min · jiezi

关于ios:MobTech-ShareSDK-iOS端快速集成

开发工具:Xcode集成形式:手动导入SDK或者Pod集成SDK版本反对:SDK反对Xcode 9.1.0, iOS8.0+及以上版本集成前筹备注册账号应用ShareSDK之前,须要先在MobTech官网注册开发者账号,并获取AppKey和AppSecret,详情能够点击查看创立利用流程 分享到第三方平台,须要当初对应第三方平台申请平台的AppKey,详情能够点击查看注册利用流程 ShareSDK流程图 增加配置获取SDK在 MobService下载核心 下载最新版本SDK 选中ShareSDK,抉择须要的平台,而后点击“保留配置”: 选中所须要的平台后,点击“下载”按钮,就会下载好SDK 舒适提醒: 各平台的左边有个问号,将鼠标搁置下来会弹出该平台的简略阐明下载下来的SDK构造 SDK目录构造阐明SDK: Required: MOBFoundation.framework (根底工具库) ShareSDK: ShareSDK.framework (主业务实现) Support: Required: ShareSDK.bundle (ShareSDK资源文件) ShareSDKConnector.framework(v4.2.0版本后已废除) PlatformConnector: ... (各个平台独立逻辑依赖库,只须要集成须要的平台即可) PlatformSDK: ... (各个平台的SDK文件,不集成默认走去SDK业务逻辑,目前反对大部分支流 平台,如QQ 微博 微信等) Optional:(可选) ShareSDKUI.bundle (分享UI的资源文件) ShareSDKUI.framework (分享UI库) ShareSDKConfigFile.framework(xml配置文件模式分享依赖库) ShareSDKConfigFile.bundle (xml配置文件模式分享资源文件) ShareSDKExtension.framework(性能的扩大框架插件。(第三方平台检测、 一键分享、截屏分享、摇一摇分享等相干性能) ShareSDKLink.framework(闭环分享库)留神:导入的时候,须要将整个SDK资源文件导入到我的项目里 导入SDK(1)手动下载SDK导入 将下面获取到的SDK,间接将整个SDK资源文件拖进我的项目里,如下图:并且勾选以下3个选项 在点击Finish,实现导入。 (2)CocoaPods引入,请参考 Pod集成 增加依赖库点击“+”号,并在弹框里输出以下依赖库,进行增加 必要依赖库: libc++.tbdlibz.tbdlibsqlite3.tbd社交平台依赖库(依据本人需要增加): 苹果登录依赖库: AuthenticationServices.frameworkFacebook依赖库: AuthenticationServices.frameworkSafariServices.frameworkAccelerate.framework新浪微博 ImageIO.frameworkPhotos.frameworkInstagram AssetsLibrary.frameworkPhotos.framework美拍 AssetsLibrary.frameworkXcode配置(1)在我的项目的Build Settings中的Other Linker Flags双击增加”-ObjC” ,留神大小写(2) 配置ShareSDK的AppKey和AppSecret,键别离为 MOBAppKey 和 MOBAppSecret ,值为之前在MobTech官网开发者后盾申请的AppKey和AppSecret(留神: 配置之后保留好,配置好后看我的项目的Info选项里有没) API接口回传用户隐衷受权后果(uploadPrivacyPermissionStatus)为保障您的App在集成MobSDK之后可能满足工信部相干合规要求,您应确保App装置首次冷启动且获得用户浏览您《隐衷政策》受权之后,调用Mob提交到的隐衷协定回传函数uploadPrivacyPermissionStatus回传隐衷协定受权后果。 ...

August 23, 2022 · 2 min · jiezi

关于ios:秒验丨iOS客户端SDK-集成指南

开发工具:Xcode集成形式:手动导入SDK或者Pod集成SDK版本反对:SDK反对Xcode 9.1.0, iOS8.0+及以上版本集成前筹备注册账号应用秒验SDK之前,须要先在MobTech官网注册开发者账号,并获取AppKey和AppSecret,详情能够点击查看创立利用流程 提交审核一键登录是运营商提供的能力,在应用秒验SDK之前,您须要在工作台提交秒验审核,详情能够点击查看秒验审核流程 秒验SDK流程图 增加配置下载SDK导入我的项目(1)手动下载SDK引入 官网下载SDK,而后将下图中SDK文件夹拖入到工程中(若我的项目中集成过秒验SDK,请将原来存在的SDK删除掉,再导入官网下载的SDK)。 (2)CocoaPods形式引入 按需在 Podfile 文件中增加命令pod 'mob_secverify' 留神 如果 pod install导入的版本不是最新版,则先执行pod repo update操作更新本地repo的内容,再从新pod install增加依赖库必要 libc++.tbd 配置Xcode我的项目Build Settings中的Other Linker Flags增加”-ObjC” 配置plist文件 (MOBAppKey和MOBAppSecret以及https)(1)在我的项目中的info.plist文件中增加键值对,键别离为 MOBAppKey 和 MOBAppSecret ,值为在之前在MobTech官网开发者后盾申请的AppKey和AppSecret:(2)ATS 配置 目前运营商个别接口为http申请,对于全局禁用Http的我的项目,须要设置Http白名单。倡议按以下形式配置Info.plist: <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>NSExceptionDomains</key> <dict> <key>zzx9.cn</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> <key>cmpassport.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> <key>id6.me</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> <key>wostore.cn</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> <key>mdn.open.wo.cn</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> <key>NSAllowsArbitraryLoads</key> <false/></dict></plist>(3)禁止上传设施信息 (2.0.6版本更新) ...

August 18, 2022 · 2 min · jiezi

关于ios:OC调用swift

在oc开发的我的项目中,咱们有时候须要用到swift开发的文件,那么怎么在oc我的项目中调用swift类呢?1.首先新建一个swift类 1551690750707.jpg 2.而后创立桥接文件 1551690776462.jpg 3.设置defines mmodule为yes 1551691529042.jpg 4.援用swift类库:”项目名称-Swift.h” 1551691036021.jpg 接下来就能够应用了。 1551691989600.jpg 作者:小羊爱学习链接:https://www.jianshu.com/p/2c2...起源:简书著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。

August 18, 2022 · 1 min · jiezi

关于ios:用代码写静态的cell

iOSExamples-StaticCellsThis project is an example for implementing a UITableView that has static cells. This pattern is often used on options pages or for creating/editing model objects. The gist is that you can create a static number of cells and store them as variables. You can then use the tableView: cellForRowAtIndexPath method to retrive the appropriate UITableViewCell variable. // Return the row for the corresponding section and row (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ switch(indexPath.section) { ...

August 17, 2022 · 2 min · jiezi

关于ios:Mac逆向手撸钉钉机器人

浏览此文档的过程中遇到任何问题,请关注公众号【挪动端Android和iOS开发技术分享】或加QQ群【812546729】1.指标钉钉在企业中的利用越来越宽泛。官网也有对应的自定义机器人服务,然而,如果1分钟内发消息超过20条,则会会限流10分钟。作为技术人,说干就干,申请个小号,手撸一个无限度的机器人。 2.操作环境mac零碎frida:动静调试工具Python:解决钉钉收到的工作Redis:钉钉和python间的通信3.流程动态剖析应用frida-trace的frida-trace -m "*[* *endMsg*]" -m "*[* *end*Message*]" 钉钉 (必须敞开Mac零碎的sip)命令跟踪钉钉。任意发送一条音讯后,发现要害日志如下: 126282 ms -[DTChatInputTextView sendMessage]126282 ms | +[DTMojoGraySwitchManager isEnableRemoveSendMessageTrim]126282 ms | +[DTMojoGraySwitchManager isTranslateSendMsgEnabled]126282 ms | | +[DTMojoGraySwitchManager isTranslateSendMsgEnabled]126282 ms | +[DTMojoGraySwitchManager isTranslateSendMsgEnabled]126282 ms | | +[DTMojoGraySwitchManager isTranslateSendMsgEnabled]126283 ms | +[DTMojoGraySwitchManager isEnableRemoveSendMessageTrim]126283 ms | -[DTChatInputTextView sendOrdinaryMessage:0x600000b2eba0]126284 ms | | -[DTChatInputTextView sendMessageByType:0x1 body:0x0 attrString:0x600000b2eba0]126284 ms | | | -[DTChatInputTextView sendMessageByType:0x1 body:0x0 attrString:0x600000b2eba0 toConversationModel:0x0]126284 ms | | | | -[DTChatInputTextView sendTxtMessageWithOption:0x0 attrString:0x600000b2eba0]126284 ms | | | | | +[DTMojoGraySwitchManager isTranslateSendMsgEnabled]126284 ms | | | | | | +[DTMojoGraySwitchManager isTranslateSendMsgEnabled]126284 ms | | | | | -[DTChatInputTextView sendTextMessage:0xd9f80e4ec6f6596b option:0x0]126284 ms | | | | | | -[DTConversationModel sendTextMessage:0xd9f80e4ec6f6596b withOption:0x0 completionHandler:0x7ffeeb4aef78]126284 ms | | | | | | | -[DTMojoMessageService sendTextMessage:0xd9f80e4ec6f6596b withCid:0x60000076d280 option:0x0 completionHandler:0x7ffeeb4aef78]126308 ms | | | | -[DTChatContentController inputTextViewDidSendMessage:0x7fd674a41400]126308 ms | +[DTMojoGraySwitchManager isTranslateSendMsgEnabled]126308 ms | | +[DTMojoGraySwitchManager isTranslateSendMsgEnabled]发现要害类DTMojoMessageService,再应用命令frida-trace -m "*[DTMojoMessageService *]" 钉钉 ,跟踪DTMojoMessageService类,去查找收到音讯调用的办法,当收到音讯后的日志如下: ...

August 11, 2022 · 3 min · jiezi

关于ios:产品说明丨-iOS-端使用-MobPush-快速集成方法

开发工具:Xcode集成形式:手动导入SDK或者Pod集成SDK版本反对:SDK反对Xcode 9.1.0, iOS8.0+及以上版本 注册账号应用PushSDK之前,须要先在MobTech官网注册开发者账号,并获取MobTech提供的AppKey和AppSecret,详情能够点击查看注册流程 MobPush流程图 获取SDK返回MobTech SDK下载页,切换iOS版下选中MobPush,并点击下载,如下图所示 下载后你应该失去一个MobPush-iOS-*.tar.gz解压后,取得文件夹如下图所示 ---- Sample // MobPush演示Demo+--- SDK // SDK文件夹,集成时需导入| ---- Required // 必要依赖库| ---- MobPush // MobPush及MobPushServiceExtension动态库导入SDK手动SDK导入 解压下载的ZIP包,将解压后的SDK文件夹增加到我的项目中。在后续选项中请抉择“Create groups”并勾选“Copy items if needed”选框。 pod导入按需在 Podfile 文件中增加如下代码,而后执行pod update即可pod 'mob_pushsdk' 增加依赖库 libc++.tbdlibz.1.2.5.tbd增加办法如下图所示 接口调用回传用户隐衷受权后果(uploadPrivacyPermissionStatus)为保障您的App在集成MobSDK之后可能满足工信部相干合规要求,您应确保App装置首次冷启动且获得用户浏览您《隐衷政策》受权之后,调用MobSDK.uploadPrivacyPermissionStatus回传隐衷协定受权后果,反之,如果用户不批准您App《隐衷政策》受权,则不能调用uploadPrivacyPermissionStatus回传隐衷协定受权后果,相干隐衷申明请参考合规指南 /** 上传隐衷协定受权状态 @param isAgree 是否批准(用户受权后的后果) @param OnResult 执行回调后果,可为nil (留神业务逻辑不要依赖于这个success后果,倡议业务逻辑在调用这个接口之后来写) */+ (void)uploadPrivacyPermissionStatus:(BOOL)isAgree onResult:(void (^_Nullable)(BOOL success))handler;示例代码 #import <MOBFoundation/MobSDK+Privacy.h>[MobSDK uploadPrivacyPermissionStatus:YES onResult:^(BOOL success) {}];设置推送环境以及配置(setAPNsForProduction) /** 设置推送环境 @param isProduction 是否生产环境。 如果为开发状态,设置为 NO; 如果为生产状态,应改为 YES。 Default 为 YES 生产状态 */+ (void)setAPNsForProduction:(BOOL)isProduction;/** 设置推送配置 @param configuration 配置信息 */+ (void)setupNotification:(MPushNotificationConfiguration *)configuration;示例代码 ...

August 11, 2022 · 1 min · jiezi

关于ios:iOS证书p12和描述文件mobileprovision申请

原文链接 : iOS证书(.p12)和形容文件(.mobileprovision)申请如果你从事过iOS开发,大略都会理解到iOS有两种证书和形容文件: 证书类型应用场景开发(Development)证书和形容文件用于开发测试,在 HBuilderX 中打包后可在真机环境调试公布(Distribution)证书和形容文件用于提交 AppStore,在 HBuilderX 中提交云打包后提交到 AppStore 审核公布如果从未接触过 iOS,依照上面教程的所需环境、步骤操作,你将学会如何制作这 两种证书 和 形容文件。 筹备环境必须要有苹果开发者账号,并且退出了 “iOS Developer Program”Mac OS 10.9以上零碎(如果曾经申请p12证书则不须要)苹果开发帐号阐明 集体账号(Individual)/公司团队账号 (Company/Organization): 费用都是99美金一年,两者无本质区别,都能够公布利用到苹果市场。 区别在于集体账号在App Store销售者只能显示集体的ID,比方san zhang,单人应用。公司团队账号在App Store销售者能够显示相似Studios,或者自定义的团队名称,比方Mamshare INC,公司账号容许多个开发者合作开发,比集体帐号多一些帐号治理和级别权限的设置。 这两种帐号都能够用于开发,但在生成开发证书的时候,须要在生成mobileprovision形容文件时把须要装置的iPhone/iPad的设施UDID进行绑定(最多能够绑定100个设施),否则生成的ipa不能失常装置到测试设施上。 企业账号 (Enterprise): 费用299美金一年,该账号开发利用不能公布到App Store,只能用于企业本人外部应用的app通过网站下载,对测试的苹果iOS设施UDID数量不限度。 生成证书申请文件不论是申请开发 (Development) 证书 还是 公布 (Distribution) 证书,都须要应用证书申请 (.certSigningRequest) 文件,证书申请文件需在Mac OS上应用 “钥匙串拜访” 工具生成。关上“钥匙串拜访”工具关上菜单 “钥匙串拜访”->“证书助理”,抉择“从证书颁发机构申请证书...”:关上创立申请证书页面,在页面中输出用户邮件地址、罕用名称,抉择存储到磁盘,点击 “持续” :文件名称为 “CertificateSigningRequest.certSigningRequest”,抉择保留地位,点击 “存储” 将证书申请文件保留到指定门路下,前面申请 开发(Development)证书 和 公布(Production)证书 时须要用到。在保留地位可看到 生成的申请证书(CertificateSigningRequest.certSigningRequest)。登录苹果开发者账号关上网站 iOS Dev Center应用苹果开发者账号登录 iOS Dev Center:登录胜利后在页面左侧抉择 “Certificates,IDs & Profiles” 进入证书治理页面:在证书治理页面,能够看到所有曾经申请的证书及形容文件:申请苹果 App ID (App的惟一标识)抉择页面的“Identifiers”可查看到已申请的所有 App 利用标识,点击页面上的加号来创立一个新的利用标识:抉择标识类型为“App”,而后点击 “Continue”平台抉择“iOS,tvOS,watchOS”,Bundle ID 抉择“Explicit”,在 Description 中填写形容,而后填写 Bundle ID,Bundle ID 要放弃唯一性,倡议填写反域名加利用标识的格局 如:“uni.xxxxxxxxx”,而后点击 “Continue” ...

August 6, 2022 · 1 min · jiezi

关于ios:iOS逆向某车之家sign签名分析

1.指标剖析某车之家sign签名算法的实现2.操作环境 fridamac零碎Charles抓包越狱iPhone3.流程寻找切入点通过Charles抓包获取到关键词为_sign,这也就是咱们的切入点: 动态剖析在动态剖析前,咱们先察看sign值的特色,比方32位就有可能是md5,数字加字母加+/而后以=号结尾的,就有可能是base64。通过肉眼察看,发现sign签名的长度是32位大写,第一直觉就是MD5,接下来间接进入动静调试去hook md5函数,看看该加密是否为md5动态分析应用frida工具的frida-trace -UF -i CC_MD5命令跟踪CC_MD5函数,代码如下: { onEnter(log, args, state) { log(`CC_MD5(${args[0].readUtf8String()})`); }, onLeave(log, retval, state) {   log(`CC_MD5()${hexdump(retval, {length:16})}`); }}执行frida-trace -UF -i CC_MD5后,点击登录按钮,日志输入如下:witchan@witchandeAir ~ % frida-trace -UF -i CC_MD5Instrumenting...CC_MD5: Loaded handler at "/Users/witchan/__handlers__/libcommonCrypto.dylib/CC_MD5.js"Started tracing 1 function. Press Ctrl+C to stop.           / TID 0x303 / 6214 ms CC_MD5(2222) 6215 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f051548 93 4b 53 58 00 b1 cb a8 f9 6a 5d 72 f7 2f 16 11 .KSX.....j]r./.. 6216 ms CC_MD5(@7U$aPOE@$Version1_appidapp.iphone_timestamp1658455619autohomeuaiPhone 12.5.5 autohome 11.25.0 iPhoneisCheckModeratorsRemote1isapp1logincode%31%31%31%31%31%31%31%31%31%31%31reffersessionida2b93cb5da721aa55ca1a87b2e919b3d3cd214e6showmob1userpwd934B535800B1CBA8F96A5D72F72F1611validcode3333@7U$aPOE@$) 6216 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f051478 50 03 73 09 75 58 bb 53 72 80 20 54 b1 39 2b d4 P.s.uX.Sr. T.9+. 6219 ms CC_MD5(https://118.116.0.118/api/Use...) 6219 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f051118 17 9a 87 99 d6 48 43 ab 69 a0 b8 62 1d d0 a8 0d .....HC.i..b.... 6221 ms CC_MD5(MGCopyAnswerDeviceName) 6221 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f0504c8 ae 4a a5 c0 f7 11 1f 08 b1 63 88 1a a4 f8 da 9f .J.......c...... 6221 ms CC_MD5(MGCopyAnswerProductVersion) 6221 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f0504c8 a8 d3 5d 76 55 0a f8 1f d8 96 8a 0d a3 29 b0 80 ..]vU........).. 6222 ms CC_MD5(MGCopyAnswerDeviceName) 6222 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f0504c8 ae 4a a5 c0 f7 11 1f 08 b1 63 88 1a a4 f8 da 9f .J.......c...... 6222 ms CC_MD5(MGCopyAnswerProductVersion) 6222 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f0504c8 a8 d3 5d 76 55 0a f8 1f d8 96 8a 0d a3 29 b0 80 ..]vU........).. 6223 ms CC_MD5(@7U$aPOE@$apisign1|a2b93cb5da721aa55ca1a87b2e919b3d3cd214e6|autohomebrush|1658455619@7U$aPOE@$) 6223 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f050498 70 c0 71 0b 37 23 3a 29 d8 44 02 d7 f6 20 a5 0c p.q.7#:).D... .. 6227 ms CC_MD5(MGCopyAnswerProductVersion) 6227 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f0527b8 a8 d3 5d 76 55 0a f8 1f d8 96 8a 0d a3 29 b0 80 ..]vU........).. 6228 ms CC_MD5(MGCopyAnswerProductVersion) 6228 ms CC_MD5()           0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF16f052748 a8 d3 5d 76 55 0a f8 1f d8 96 8a 0d a3 29 b0 80 ..]vU........)..           / TID 0x552bf /搜寻 _sign值500373097558BB5372802054B1392BD4后发现后果: ...

August 4, 2022 · 3 min · jiezi

关于ios:iOS逆向之某多多App抓包

1.指标因为某多多App现应用longlink进行数据传输,应用charles工具抓包只能抓到https://th.pinduoduo.com/t.gif链接。本文的目则是应用charles等抓包工具能失常抓包 2.操作环境 越狱iPhone一台frida3.流程下载最新某多多App。关键词longlink则是咱们的切入点,在终端执行frida-trace -U -f com.xunmeng.pinduoduo -m "[ ongink]" -M "[UI ]" -M "[_ *]"命令后获取到要害信息列表: +[AMTitanHelper makesureLongLinkConnect:]: Loaded handler at "/Users/witchan/__handlers__/AMTitanHelper/makesureLongLinkConnect_.js"-[AMTitanLongLinkInfoManager updateLongLinkStatusInfoWithHost:longLinkStatus:longLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/AMTitanLongLinkInfoManager/updateLongLinkStatusInfoWithHost_663278c1.js"-[AMTitanLongLinkInfoManager longLinkStatusInfoDic]: Loaded handler at "/Users/witchan/__handlers__/AMTitanLongLinkInfoManager/longLinkStatusInfoDic.js"-[AMTitanLongLinkInfoManager setLongLinkStatusInfoDic:]: Loaded handler at "/Users/witchan/__handlers__/AMTitanLongLinkInfoManager/setLongLinkStatusInfoDic_.js"-[PDDProbeRaceManager longLinkRaceResult:traceId:reportBlock:callback:]: Loaded handler at "/Users/witchan/__handlers__/PDDProbeRaceManager/longLinkRaceResult_traceId_repor_9af8c15b.js"-[AMTitanNetworkConfig setLonglinkHostConfig:]: Loaded handler at "/Users/witchan/__handlers__/AMTitanNetworkConfig/setLonglinkHostConfig_.js"-[AMTitanNetworkConfig longlinkHostConfig]: Loaded handler at "/Users/witchan/__handlers__/AMTitanNetworkConfig/longlinkHostConfig.js"+[PDDNetworkHybrid longLinkErrorCodeMap]: Loaded handler at "/Users/witchan/__handlers__/PDDNetworkHybrid/longLinkErrorCodeMap.js"-[PddRtc titan:didChangeToConnectionStatus:longLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/PddRtc/titan_didChangeToConnectionStatu_745d0013.js"-[PDDWebConfig htmlLongLinkWhiteListFromConfig]: Loaded handler at "/Users/witchan/__handlers__/PDDWebConfig/htmlLongLinkWhiteListFromConfig.js"-[PDDWebConfig setHtmlLongLinkWhiteList:]: Loaded handler at "/Users/witchan/__handlers__/PDDWebConfig/setHtmlLongLinkWhiteList_.js"-[PDDWebConfig htmlLongLinkWhiteList]: Loaded handler at "/Users/witchan/__handlers__/PDDWebConfig/htmlLongLinkWhiteList.js"-[PDDWebViewManager pdd_setProtocolLongLinkEnable:]: Loaded handler at "/Users/witchan/__handlers__/PDDWebViewManager/pdd_setProtocolLongLinkEnable_.js"-[PDDLiveRoomMicLinkManager registerLongLinkMsgCenter]: Loaded handler at "/Users/witchan/__handlers__/PDDLiveRoomMicLinkManager/registerLongLinkMsgCenter.js"+[PDDTitanNetworkConfig mainLongLinkBackupIps]: Loaded handler at "/Users/witchan/__handlers__/PDDTitanNetworkConfig/mainLongLinkBackupIps.js"+[PDDTitanNetworkConfig multicastLongLinkBackupIps]: Loaded handler at "/Users/witchan/__handlers__/PDDTitanNetworkConfig/multicastLongLinkBackupIps.js"-[AMNetworkInfoManager longLinkInfo]: Loaded handler at "/Users/witchan/__handlers__/AMNetworkInfoManager/longLinkInfo.js"-[AMNetworkInfoManager setLongLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/AMNetworkInfoManager/setLongLinkInfo_.js"+[AMNetworkInfo longLinkInfo]: Loaded handler at "/Users/witchan/__handlers__/AMNetworkInfo/longLinkInfo.js"+[AMNetworkInfo setLongLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/AMNetworkInfo/setLongLinkInfo_.js"-[AMHTTPRequest longLinkDowngrade]: Loaded handler at "/Users/witchan/__handlers__/AMHTTPRequest/longLinkDowngrade.js"-[AMHTTPRequest setLongLinkDowngrade:]: Loaded handler at "/Users/witchan/__handlers__/AMHTTPRequest/setLongLinkDowngrade_.js"-[PDDAntManager titan:didChangeToConnectionStatus:longLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/PDDAntManager/titan_didChangeToConnectionStatu_745d0013.js"-[PDDApiMetricsBaseInfo setIsLongLinkReceived:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsBaseInfo/setIsLongLinkReceived_.js"-[PDDApiMetricsBaseInfo setLongLinkVip:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsBaseInfo/setLongLinkVip_.js"-[PDDApiMetricsBaseInfo setLongLinkErrorCode:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsBaseInfo/setLongLinkErrorCode_.js"-[PDDApiMetricsBaseInfo setLongLinkType:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsBaseInfo/setLongLinkType_.js"-[PDDApiMetricsBaseInfo isLongLinkReceived]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsBaseInfo/isLongLinkReceived.js"-[PDDApiMetricsBaseInfo longLinkVip]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsBaseInfo/longLinkVip.js"-[PDDApiMetricsBaseInfo longLinkErrorCode]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsBaseInfo/longLinkErrorCode.js"-[PDDApiMetricsBaseInfo longLinkType]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsBaseInfo/longLinkType.js"-[PDDApiMetricsCostInfo setLongLinkSendCost:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsCostInfo/setLongLinkSendCost_.js"-[PDDApiMetricsCostInfo setLongLinkRecvCost:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsCostInfo/setLongLinkRecvCost_.js"-[PDDApiMetricsCostInfo setLongLinkServerCost:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsCostInfo/setLongLinkServerCost_.js"-[PDDApiMetricsCostInfo longLinkSendCost]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsCostInfo/longLinkSendCost.js"-[PDDApiMetricsCostInfo longLinkRecvCost]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsCostInfo/longLinkRecvCost.js"-[PDDApiMetricsCostInfo setLongLinkNetworkCost:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsCostInfo/setLongLinkNetworkCost_.js"-[PDDApiMetricsCostInfo longLinkServerCost]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsCostInfo/longLinkServerCost.js"-[PDDApiMetricsCostInfo longLinkNetworkCost]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsCostInfo/longLinkNetworkCost.js"-[PDDApiMetricsExtraInfo setLongLinkReportCode:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/setLongLinkReportCode_.js"-[PDDApiMetricsExtraInfo setLongLinkStatusCode:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/setLongLinkStatusCode_.js"-[PDDApiMetricsExtraInfo setLongLinkTaskId:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/setLongLinkTaskId_.js"-[PDDApiMetricsExtraInfo setLongLinkSendSize:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/setLongLinkSendSize_.js"-[PDDApiMetricsExtraInfo setLonglinkReceiveSize:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/setLonglinkReceiveSize_.js"-[PDDApiMetricsExtraInfo setLongLinkForeground:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/setLongLinkForeground_.js"-[PDDApiMetricsExtraInfo setLongLinkUrl:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/setLongLinkUrl_.js"-[PDDApiMetricsExtraInfo longLinkReportCode]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/longLinkReportCode.js"-[PDDApiMetricsExtraInfo longLinkStatusCode]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/longLinkStatusCode.js"-[PDDApiMetricsExtraInfo isLongLinkForeground]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/isLongLinkForeground.js"-[PDDApiMetricsExtraInfo longLinkSendSize]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/longLinkSendSize.js"-[PDDApiMetricsExtraInfo longlinkReceiveSize]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/longlinkReceiveSize.js"-[PDDApiMetricsExtraInfo longLinkTaskId]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/longLinkTaskId.js"-[PDDApiMetricsExtraInfo longLinkUrl]: Loaded handler at "/Users/witchan/__handlers__/PDDApiMetricsExtraInfo/longLinkUrl.js"-[PDDApiWaitLonglinkConfig isWaitLonglink:method:]: Loaded handler at "/Users/witchan/__handlers__/PDDApiWaitLonglinkConfig/isWaitLonglink_method_.js"-[AMTitan updateLongLinkHostWhiteList:]: Loaded handler at "/Users/witchan/__handlers__/AMTitan/updateLongLinkHostWhiteList_.js"-[AMTitan updateLongLinkUriBlackList:]: Loaded handler at "/Users/witchan/__handlers__/AMTitan/updateLongLinkUriBlackList_.js"-[AMTitan isLongLinkConnected]: Loaded handler at "/Users/witchan/__handlers__/AMTitan/isLongLinkConnected.js"-[AMTitan makesureLongLinkConnect:]: Loaded handler at "/Users/witchan/__handlers__/AMTitan/makesureLongLinkConnect_.js"-[AMTitan reportStatusChange:longLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/AMTitan/reportStatusChange_longLinkInfo_.js"-[AMTitan onConnectStatusChange:longLinkStatus:longLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/AMTitan/onConnectStatusChange_longLinkSt_c4a1163e.js"-[AMTitanBaseRequest setWaitLonglink:]: Loaded handler at "/Users/witchan/__handlers__/AMTitanBaseRequest/setWaitLonglink_.js"-[AMTitanBaseRequest waitLonglink]: Loaded handler at "/Users/witchan/__handlers__/AMTitanBaseRequest/waitLonglink.js"-[AMTitanStnCallback reportConnectStatus:longLinkStatus:longLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/AMTitanStnCallback/reportConnectStatus_longLinkStat_1d404d83.js"-[AMTitanTask setWaitLonglink:]: Loaded handler at "/Users/witchan/__handlers__/AMTitanTask/setWaitLonglink_.js"-[AMTitanTask waitLonglink]: Loaded handler at "/Users/witchan/__handlers__/AMTitanTask/waitLonglink.js"+[AMTitanTransferUtil transferToLongLinkInfo:]: Loaded handler at "/Users/witchan/__handlers__/AMTitanTransferUtil/transferToLongLinkInfo_.js"通过一层层筛查打印以上办法的入参和返回值,当批改到[AMTitan updateLongLinkHostWhiteList:]办法时,输入的日志参数,引起了咱们的留神,updateLongLinkHostWhiteList_.js代码如下: ...

August 4, 2022 · 3 min · jiezi

关于ios:iOS逆向某茅台App抓包

1.指标因为某茅台App有抓包检测,无奈间接应用charles等工具抓包。本文的目标天然就是如何批改源码并抓任意接口 2.依赖环境frida-ios-dump:用来砸壳。官网 https://github.com/AloneMonke...ida pro:批改源码 3.流程手机上安装最新版本的茅台App,执行dump.py com.moutai.mall命令后获取到砸壳后的app。拖到ida pro工具,编译实现后。全局搜寻SVC指令:image-20220714172208698搜寻后果如下:双击sub_100310B80进入到该函数 image-20220714180543527在ida pro界面,任意选中左侧的函数,而后顺次点击工具栏的Search -> Search后,弹出搜寻框,在搜寻框输出CFNetworkCopySystemProxySettings找到该函数:从界面上可看出,有两个处代码有应用该函数,接下来就是对这两处代码进行批改进入第一个函数,把CBZ X0, loc_1002A09F4替换为B loc_1002A09F4进入第二个函数,把CBZ X0, loc_1002A0D18替换为B loc_1002A0D18 到这一步后,ipa源码咱们曾经批改实现。导出二进制文件用导出的二进制文件替换掉ipa里的二进制文件。而后把charles工具的证书导出。替换到ipa文件里的MT.cer。最初用重签名工具进行重签名。就能够装置到你的非越狱机上了。最终抓包后果如下:![图片] End

August 4, 2022 · 1 min · jiezi

关于ios:oc与swift文件的相互调用方式桥接

刚好看书的时候看到这里,网上对于桥接的形容也是挺乱的,当年还比拟菜鸟的时候查找这个问题也不是没被坑过,顺便记录一下不便一下其他人。一、设置桥接文件不论是objective-c调用swift,还是swift调用objective-c,都须要创立桥接文件,通过桥接文件实现两者的互相调用。当咱们引入oc或者swift进入另一个语言的我的项目的时候零碎会提醒是否主动创立桥接文件,此时可间接创立。但除此之外咱们也能够抉择手动创立。此时须要咱们在新建文件里抉择Header File,点击确认创立桥接文件,桥接文件名字个别为:ProjectName-Bridging-Header.h。而后在Build settings里搜寻bridging,找到Objective-C Bridging Header的选项,将该文件的门路填写进去,或者间接拉入。这里的门路最好抉择相对路径的模式(ProjectName/BridgingFileName.h)。ProjectName为你我的项目的我的项目名,BridgingFileName为桥接文件的名字。 二、桥接办法oc我的项目调用swift文件oc我的项目针对swift文件会主动创立ProjectName-Swift.h文件,该文件不须要咱们去做更改,所以当咱们设置完桥接文件之后,只须要在要调用的文件处import该头文件即可,即:import <ProjectName-Swift.h>,其中ProjectName为该项目标工程名。引入该头文件后,即可调用Swift对应的类和办法。 留神点:引入的swift文件须要调用的类和办法须要进行润饰,而后oc我的项目能力调用。可应用@objcMembers间接润饰类,或者也能够应用@objc别离润饰想要调用给oc的办法和属性,而后oc我的项目就可调用swift的相干办法了。 swift我的项目调用oc文件swift我的项目调用oc文件更为简略,只须要将oc类的头文件导入桥接文件即可,须要调用哪个oc文件就import哪个头文件(#import "ClassName.h")进去。swift我的项目调用oc的类和办法不须要引入头文件,所以设置完之后能够间接在swift中间接调用oc办法。 留神点:须要被调用的oc文件的办法须要写在.h文件里进行办法申明(废话)。

August 2, 2022 · 1 min · jiezi

关于ios:Swift高仿iOS网易云音乐MoyaRxSwiftKingfisherMVCMVVM

成果 列文章目录因为目录比拟多,每次更新这里比拟麻烦,所以举荐点击到主页,而后查看iOS Swift云音乐专栏。 目简介这是一个应用Swift(还有OC版本)语言,从0开发一个iOS平台,靠近企业级的我的项目(我的云音乐),蕴含了根底内容,高级内容,我的项目封装,我的项目重构等常识;次要是应用零碎性能,风行的第三方框架,第三方服务,实现靠近企业级商业级我的项目。 目性能点隐衷协定对话框启动界面和动静解决权限疏导界面和广告轮播图和侧滑菜单首页简单列表和列表排序音乐播放和音乐列表治理全局音乐管制条桌面歌词和自定义款式全局媒体控制中心评论和回复评论评论富文本点击评论揭示人和话题朋友圈动静列表和公布高德地图定位和门路布局阿里云OSS上传视频播放和管制QQ/微信登录和分享商城/购物车\微信\支付宝领取文本和图片聊天音讯离线推送主动和手动查看更新内存透露和优化... 发环境概述2022年7月开发实现的,所以全部都是最新的,均匀每3年会从新制作,当初曾经是第三版了。 Xcode 13.4iOS 15译和运行先装置pod,用最新Xcode关上MyCloudMusic.xcworkspace,而后运行,如果要运行到真机,先登陆本人的开发者账户,如果不是付费账户,请删除推送等付费性能,更改BundleId,而后运行。 目目录构造├── MyCloudMusic│ ├── AppDelegate.swift│ ├── Assets.xcassets #资源目录│ ├── Base.lproj│ ├── Cell #通用cell│ ├── Component #每个功能模块│ │ ├── Ad #广告相干│ │ ├── Address #播种地址相干│ ├── Config #配置目录,例如:网络地址配置│ ├── Controller #通用控制器│ ├── Extension #扩大,例如:字符串扩大│ ├── Info.plist│ ├── Manager #管理器,例如:音乐播放管理器│ ├── Model #通用模型│ ├── MyCloudMusic-Bridging-Header.h│ ├── MyCloudMusic.entitlements│ ├── Repository #数据仓库,例如:网络申请封装│ ├── Service #数据服务,例如:网络api│ ├── UI #通用UI模型│ ├── Util #工具类│ ├── Vender #通过源码形式依赖的第三方框架│ ├── View #通用View├── MyCloudMusic.xcodeproj├── MyCloudMusic.xcworkspace├── MyCloudMusicTests #测试相干├── MyCloudMusicUITests #UI测试相干├── Podfile├── Podfile.lock└── R.generated.swift #R.swfit框架生成的文件赖框架内容太多,只列出局部。 ...

July 31, 2022 · 18 min · jiezi

关于ios:项目RTL语言适配实践中遇到的问题和总结

图片来自:https://picography.co/ocean-s... 本文作者:JDMin开篇当今大概有超过 22 个国家,6.6 亿人应用阿拉伯文字,使其成为仅次于拉丁文和中文的世界第三大书面语言。随着业务在海内扩大的逐步深刻,App 适配阿拉伯语曾经提上了日程。与咱们平时接触较多的中英文区别最显著的是,阿拉伯语的书写和应用习惯是从右到左的。只管 iOS 自身曾经有很多对于这种 RTL(Right-To-Left) 语言的解决,然而在咱们开发的时候,须要留神应用正确的标准去防止谬误。同时每个业务和 App 都有各自的一些非凡设计和其余特点,这些特点也会带来许多新的问题待解决。上面介绍下最近工程在适配RTL语言中遇到的问题和解决。 在介绍具体的各个问题场景前,咱们先对 RTL 语言与工程适配相干的一些次要特点做下介绍: 文本。与中文、英文等 LTR(Left-To-Right) 语言最显著的不同是,RTL 语言在书写和浏览习惯上是从右到左的。图标。图标要针对每个具体图标灵活处理。思考到 RTL 语言的文案和应用习惯是从右到左,所以很多有明确方向性的图标须要扭转下方向(举个例子来说,比方罕用的箭头图标)。至于其余常规性图标,则在 UI 中放弃不变。数字。咱们日常接触较多是阿拉伯数字,或者称作西阿拉伯数字。与之绝对的,是东阿拉伯数字。不同的阿拉伯国家应用不同的阿拉伯数字,比方摩洛哥、阿尔及利亚罕用西阿拉伯数字,而伊朗、阿富汗、巴基斯坦等国家则应用东阿拉伯数字。而像埃及、沙特阿拉伯等国家,则两种模式的阿拉伯数字都会应用。开发前须要确认分明咱们须要提供服务的地区应用的是哪种阿拉伯数字,并且正确的解决和展现。工程现状和特点实际上,iOS 零碎曾经对RTL语言做了诸多解决,并且提供了许多 API 不便下层做业务适配。不过在探讨这些具体的问题之前,咱们须要先理解以后工程的现状和特点,并依此来抉择最合适的解决计划。总结来说,工程以后的几个特点: 体量较大。工程倒退到明天,代码量曾经比拟宏大。对于比拟大的改变须要思考革新老本,以及是不是会对未来业务扩大落下什么隐患。工程有大量的布局代码,特地是比拟晚期的业务的布局代码,是应用frame layout手动布局的形式解决,没有应用AutoLayout。App反对用户利用内设置语言。利用首次启动会抉择用户的零碎语言作为默认语言,同时反对用户在利用内切换语言。至于布局形式、利用内设置语言对 RTL 适配的具体影响,咱们在后文具体介绍。 遇到的问题利用内切换语言当咱们在零碎设置中将语言设置为阿拉伯语等 RTL 语言后,零碎会主动将 App 的布局形式改为 RTL 布局。这里就会遇到第一个问题,咱们 App 内能够设置语言,当利用设置语言和零碎语言的布局形式不统一时(比方利用内设置成阿拉伯语,零碎设置成英语),咱们心愿以利用内语言为准。这个时候,就无奈再应用零碎的默认解决。在 iOS9 当前,iOS 为UIView 凋谢了一个新的property , @property (nonatomic) UISemanticContentAttribute semanticContentAttribute API_AVAILABLE(ios(9.0));通过semanticContentAttribute 能够在由开发者自定义一个 view 在 RTL 和 RTL 布局下是否做翻转解决。咱们须要依据利用内语言设置App里 View 的semanticContentAttribute ,防止应用零碎的默认判断。这里对一个个 View 做改变显然过于麻烦,咱们的做法是在语言设置的时候,通过设置UIView.appearance().semanticContentAttribute依据对全局做解决。 if isRTLLanguage { UIView.appearance().semanticContentAttribute = .forceRightToLeft} else { UIView.appearance().semanticContentAttribute = .forceLeftToRight}对于有非凡适配场景的 View (在RTL模式下也不翻转),能够在业务顶层自行设置相干 UI 元素实例的semanticContentAttribute 。 ...

July 27, 2022 · 4 min · jiezi

关于ios:iOS-越狱机子HTTPS抓包

iOS 越狱机子HTTPS抓包,须要装置SSL Kill Switch2插件

July 22, 2022 · 1 min · jiezi

关于ios:不想折腾-python-环境又想跨平台进行-iOS-自动化怎么办不妨试试-sib

前言官网文档(下载、装置、文档):https://sonic-cloud.gitee.io/...用户社区(提bug、需要): https://sonic-cloud.wiki/Github: https://github.com/SonicCloud... sib介绍sib是以gidevice为底层实现的iOS调试工具,因为go语言个性,编译好的二进制文件能够间接运行,所以不须要额定配置python环境或者go环境,间接下载3M左右的包解压就能够应用啦!sonic组织也在继续参加建设gidevice。以后迭代了数月,达到了1.1.2版本,根底性能如下: 设施根底信息获取、设施监听App装置卸载、启动终止查看过程信息启动xctest相干,如:启动Wda、Fastbot_iOS获取电池相干信息重启关机代理转发解体信息收集模仿定位与勾销(局部App不失效)屏幕旋转监听系统日志获取性能采集(Doing)截图(Doing)以上性能皆跨平台,即Windows、Mac、Linux都能够应用。 UI自动化的利用(Appium)以Java为例:先用sib启动wda(须要指定端口能够参考官网文档的参数) sib run wda而后在脚本里配置Driver DesiredCapabilities desiredCapabilities = new DesiredCapabilities(); desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, Platform.IOS); desiredCapabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); desiredCapabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 3600); desiredCapabilities.setCapability(IOSMobileCapabilityType.COMMAND_TIMEOUTS, 3600); desiredCapabilities.setCapability(MobileCapabilityType.NO_RESET, true); desiredCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, 【设施名称,也能够通过sib获取】); desiredCapabilities.setCapability(MobileCapabilityType.UDID, udId); desiredCapabilities.setCapability("wdaConnectionTimeout", 60000); desiredCapabilities.setCapability(IOSMobileCapabilityType.WEB_DRIVER_AGENT_URL, "http://127.0.0.1:8100"); desiredCapabilities.setCapability("useXctestrunFile", false); desiredCapabilities.setCapability(IOSMobileCapabilityType.SHOW_IOS_LOG, false); desiredCapabilities.setCapability(IOSMobileCapabilityType.SHOW_XCODE_LOG, false); desiredCapabilities.setCapability("skipLogCapture", true); desiredCapabilities.setCapability(IOSMobileCapabilityType.USE_PREBUILT_WDA, false); new IOSDriver("http://localhost:4723/wd/hub", desiredCapabilities);即可启动。 在Fastbot利用sib run xctest -b bytedance.FastbotRunner.xxxxxxx.xctrunner -e BUNDLEID=com.xxxxxx.internalapp -e duration=1 -e throttle=500留神,因为wda和fastbot局部底层是雷同,所以同时启动wda和fastbot会阻塞哦 获取App图标加上-i参数即可获取icon,格局为base64 sib app list -i前端渲染后成果如图 屏幕旋转监听sib orientation您会取得相似的输入 orientation: 1 结语sib还在继续更新中,正在开掘无人触碰的畛域,也欢送有能力的小伙伴参加建设 ~

July 22, 2022 · 1 min · jiezi

关于ios:ios-一个xib添加多个cell

ios 一个xib注册多个cell一、创立多个Cell首次应用xib创立UITableviewCell的时候,我都是一个xib文件里,只创立一个Cell,在理论业务中,往往都是一个列表中须要用到多个不同的Cell款式,这就须要创立N个.h .m .xib文件。而且这些.m中的实现还差不多 1、在一个xib中创立多个Cell先和一般创立xibCell一样,在xib中选中右边那个Cell,copy(command + c)或者在拖一个UITableViewCell下来,而后paste(command + v),.xib中就多个Cell了。 2、设置Restoration ID为每个Cell 设置一个惟一的 Restoration ID, 二、应用- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //在重用队列中 找到正确的Cell 重复使用Cell SpotStrategyParamCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CirculationOptionalID"]; if (!cell) { // 从 mainBundle 中加载资源 cell = [[[NSBundle mainBundle] loadNibNamed:@"SpotStrategyParamCell" owner:self options:nil] objectAtIndex:2]; } cell.selectionStyle = UITableViewCellSelectionStyleNone; return cell;}三、属性问题新拖进来三个cell下面放好控件增加过束缚后,开始拖拽管制为属性,可是每次关联的都是第一个cell,最初查看发现是因为新的几个cell是从控件库中拖拽进去的没有和某个类关联,也就是相当于是一个空的cell跟那个都无关,所以无论怎么拖拽都是关联的第一个cell。 点击cell查看属性查看器通过属性查看器和cell某个控件关联,而后在拖拽为属性。提前在.h文件中定义好属性,间接和控件关联,如果有多个cell会有抉择关联某个cell选项。留神⚠️:关联属性的时候,你想关联那个Cell上的属性,须要先点击右边Cell列表,选中该Cell,而后再拖线关联下面的控件。 应用拖拽到.m文件关联的形式所有属性会关联到第一个cell上, 如下图: 咱们须要独自选中右边的每个cell,查看属性查看器通过属性查看器和cell某个控件关联,而后在拖拽为属性。如图:

July 18, 2022 · 1 min · jiezi

关于ios:小米被指违反-GPL-协议iOS-16-公测版发布Go-119-RC1-发布-思否周刊

40s 新闻速递iOS 16 公测版公布马斯克终止收买推特,推特股价大跌国内手机厂商支流手机机型已切换 Type-C 接口微信测试聊天图片发送下限 99 张音讯称苹果汽车最新设计将采纳面对面座椅,勾销方向盘和刹车踏板谷歌 Chrome OS 正式更名为 ChromeOS:只差一个空格小米被指违反 GPL 协定微软推出 Visual Studio Code Server 近程开发服务比尔 · 盖茨:将来会捐出简直全副财产Go 1.19 RC1 公布Android 13 最初一个测试版公布Dapr 1.8 公布Redis 7.0.3 公布Visual Studio 2022 v17.2.6 公布行业资讯iOS 16 公测版公布近日,苹果面向 iPhone 和 iPad 用户推送了 iOS/iPadOS16 公测版 Beta1 更新。iPhone 8 及之后上市的机型可进行体验。其中备受期待自定义锁屏来了,锁定屏幕上的小组件让用户可能速览所需信息,如行将开始的日历日程、天气、电池电量、闹钟、时区以及流动圆环的进度等更多内容。 马斯克终止收买推特,推特股价大跌推特股价周一开盘大跌 11.3%,报 32.65 美元,创下 2021 年 4 月以来最大单日跌幅,市值蒸发约 32 亿美元。特斯拉股价周一亦走低,开盘大跌 6.55%,报 703.03 美元。推特周一盘后示意,马斯克和马斯克代表宣称的终止协定行为是“有效和谬误的”。推特未违反其在协定下的任何任务,将持续依据协定提供马斯克合理要求的信息,并致力采取所有必要的措施来实现交易。Rosenblatt Securities 分析师周一早些时候示意称,如果马斯克收买推特的交易未能产生,后者股价可能会暴涨至 11 美元。(新 国内手机厂商支流手机机型已切换 Type-C 接口近日,欧洲议会和欧盟理事会代表达成统一,批准到 2024 年,对立欧盟区域内所有便携式电子设备充电接口为 USB Type-C。记者理解到,截至目前,国内手机厂商推出的支流机型均已切换为 Type-C 接口。欧洲议会公报还指出,对反对疾速充电的设施充电速度也要对立。在我国,手机快充技术标准化也在一直推动,多家手机企业、芯片企业独特参加,为后续相干国家标准研制奠定根底。 ...

July 16, 2022 · 2 min · jiezi

关于ios:ios-逆向之基于theos打包

iOS逆向大部分工具都是基于THEOS跨平台打包工具,比如说此例子,咱们来先来说说Theos打包的makefile打包,先介绍一下包里的构造 #theos指令装置手机ipTHEOS_DEVICE_IP = localhost -o StrictHostKeyChecking=no#theos指令装置手机端口THEOS_DEVICE_PORT = 2222#ARCHS = arm64 arm64e#指定架构ARCHS = arm64#TARGET = iphone:clang:14.5:9.0#iphone示意是打手机类型,14.5示意是iphoneosSDk版本为14.5 9.0示意最低兼容版本TARGET = iphone:14.5:9.0#指定hook的过程为lockdowndINSTALL_TARGET_PROCESSES = lockdownd#这个应该是固定要导入的依赖关系include $(THEOS)/makefiles/common.mk#领导编译tweek名称TWEAK_NAME = XcodeRootDebug#领导tweak编译那些文件,格局为tweak名字_FILES等等XcodeRootDebug_FILES = Tweak.xXcodeRootDebug_CFLAGS = -fobjc-arc#XcodeRootDebug_FRAMEWORKS = UIKit CoreFoundation Foundation#须要导入tweak编译依赖的mk文件include $(THEOS_MAKE_PATH)/tweak.mk#领导编译bundle名称BUNDLE_NAME = XcodeRootDebugPrefs#指定编译的Files,名称格局为 bundle名字_FILES 等等XcodeRootDebugPrefs_FILES = XRDRootListController.m#指定依赖的库XcodeRootDebugPrefs_FRAMEWORKS = UIKit CoreFoundation Foundation#指定依赖的公有库XcodeRootDebugPrefs_PRIVATE_FRAMEWORKS = Preferences#指定bundle的在手机上的装置目录XcodeRootDebugPrefs_INSTALL_PATH = /Library/PreferenceBundlesXcodeRootDebugPrefs_CFLAGS = -fobjc-arc#导入bundle编译依赖的mkinclude $(THEOS_MAKE_PATH)/bundle.mk这里有两个坑,theos须要本人下载SDKS库,而不是用零碎的SDK库,通过下载链接下载复制到Theos装置目录sdks文件夹下,我电脑是/opt/theos/sdks,这里和TARGET = iphone:14.5:9.0中的14.5绝对应,如果/opt/theos/sdks门路下,没有对应的sdk版本,则会编译报错 make打包命令make package参照:https://my.oschina.net/zhangk...https://github.com/theos/sdkshttps://github.com/theos/theo...https://wizardforcel.gitbooks...

July 15, 2022 · 1 min · jiezi

关于ios:iOS-xib-快捷键备忘

iOS快捷键备忘command + d 复制以后选中的控件option + 鼠标左键拖动 复制拖动的控件control + 鼠标左键与其余控件连线 设置与其余控件的依赖关系command + option + = 更新以后束缚地位(以后束缚残缺且控件地位与束缚地位不符的时候能够失效)

July 15, 2022 · 1 min · jiezi

关于ios:Swift-中的-JSON-反序列化

图片来自:https://unsplash.com/photos/f... 本文作者:无帆业界罕用的几种计划手动解码计划,如 Unbox(DEPRECATED)Swift 晚期广泛采纳的计划,相似的还有 ObjectMapper 该计划须要使用者手动编写解码逻辑,应用老本比拟高;目前已被 Swift 官网推出的 Codable 取代 示例: struct User { let name: String let age: Int}extension User: Unboxable { init(unboxer: Unboxer) throws { self.name = try unboxer.unbox(key: "name") self.age = try unboxer.unbox(key: "age") }}阿里开源的 HandyJSONHandyJSON 目前依赖于从 Swift Runtime 源码中推断的内存规定,间接对内存进行操作。 在应用方面,不须要繁冗的定义,不须要继承自 NSObject,申明实现了协定即可 示例: class Model: HandyJSON { var userId: String = "" var nickname: String = "" required init() {}}let jsonObject: [String: Any] = [ "userId": "1234", "nickname": "lilei",] let model = Model.deserialize(from: object)然而存在兼容和平安方面的问题,因为强依赖内存布局规定,Swift 大版本升级时可能会有稳定性问题。同时因为要在运行时通过反射解析数据结构,会对性能有肯定影响 ...

July 15, 2022 · 9 min · jiezi

关于ios:百度APP-iOS端内存优化实践大块内存监控方

01 背景内存不足引发的APP解体通常称为OOM(Out Of Memory),iOS端无奈捕捉OOM异样,也得不到任何堆栈信息,给咱们排查和解决问题带来很多困扰。引起OOM的起因归根结底就是因为内存调配不合理引起的,尤其是内存处于危险水位时单次内存调配过大引起Jetsam机制开始失效而杀掉过程,通过咱们线上数据监控,百度APP客户端单次内存调配超过30M的case很多。 针对这种潜在的引起OOM的隐患,咱们开发了一种大内存调配监控计划,充分利用线上监控劣势(丰盛实在的用户场景和用户门路)和线下流水线劣势(可获取更多的堆栈信息),其中线上环境除了性能实现外,还要重点思考稳定性,不能引入额定的性能问题,通过技术摸索咱们解决了此类难题,线上监控和线下流水线监控相结合实现对百度APP大块内存的监控。 02 技术计划综述大块内存监控大体分为两个功能模块,缺一不可: 获取内存调配详情。判断单次内存调配是否超过阈值,若超过阈值,阐明是大内存调配行为;获取堆栈信息。丰盛的堆栈信息可间接帮忙开发同学定位到产生大内存调配的具体代码,定位调配不合理的case。最终可通过优化内存调配不合理的case,达到升高OOM率的指标。 03 获取内存调配详情3.1 计划比照 对于获取iOS端每次内存调配信息,有如下解决方案: 通过 hook 内存调配函数 alloc 办法获取,用 swizzle 办法实现 hook,存在的毛病是监控范畴不够全面,只能监控 OC 对象,不能监控 C/C++ 对象。hook 库libsystem\_malloc 内存调配函数 malloc\_zone\_malloc、malloc\_zone\_calloc、malloc\_zone\_valloc、malloc\_zone\_realloc来获取内存信息。这种计划对于 OC 对象和 C/C++ 对象都可监控,然而因为要 hook 零碎 C/C++ 办法而不是 OC 办法,目前的技术条件须要应用 fishhook。 百度APP 采纳的技术计划如下图所示,首先通过重置 libsystem\_malloc 库中的malloc\_logger 函数指针获取内存流动详情(调配和开释两种流动),而后通过Type类型过滤出内存调配的流动, 最初获取内存调配大小,该计划可监控 OC 对象和 C/C++ 对象,对iOS框架零碎没有侵入性,没有用 fishhook 库所以没有对 mach-o 文件做任何批改,也没有 hook 任何底层分配内存零碎办法,从 APP 性能和品质角度来说是最好的抉择。 3.2 libsystem\_malloc源码剖析 libsystem\_malloc.dylib 是iOS零碎虚拟内存治理的外围库之一,任何波及到OC、C/C++ 对象的内存调配都会调用该库的API,由它去调用操作系统Mach内核提供的接口去调配或开释内存。具体来说 libsystem\_malloc 提供了 malloc\_zone\_malloc,malloc\_zone\_calloc,malloc\_zone\_valloc,malloc\_zone\_realloc,malloc\_zone\_free 五个API来实现内存调配和开释,在 iOS 零碎中所有波及到的内存流动都会调用如上接口,当咱们App过程须要创立新的对象时,如调用 [NSObject alloc],或开释对象调用 release 办法时(编译器会增加),申请先会走到 libsystem\_malloc.dylib 的上述函数。 ...

July 14, 2022 · 2 min · jiezi

关于ios:iOS-initfunc-函数hook

https://github.com/everettjf/... https://everettjf.github.io/2...

July 8, 2022 · 1 min · jiezi

关于ios:如何将16进制转换为中文

1.如果是iDA中的16进制,选中16进制所在地址,快捷键alt+A键,抉择unicode 16编码即可转换为中文2.第二能够在010 Editor里增加16进制数据转换编码unicode即为中文留神第一步:1.新建一个文件,从其余文件处复制16进制数据,在010 Editor抉择Edit-->Paste From-->Paste from Hex Text @2.抉择编码Unicode 其余:如何将IDA中大段数据,放在一起容易copy1.抉择要copy的起始地址,抉择Edit-->Array,点击ok转换成数组复制出数据,记住独自byte为0时须要填充为00最终失去十六进制数据:8B4EF64EB970FB512D002D002D002D007400610062006C0065005600690065007700555343513C68B970FB51

July 8, 2022 · 1 min · jiezi

关于ios:iOS-隐式调用SVC

出于利用平安防护的目标,平安开发人员为避免函数被HOOK(inlinehook/fishhook),个别会对敏感函数做SVC调用,如access/stat/open等函数。做SVC调用的形式显著因为间接调用和动静dlsym调用,隐蔽性失去加强,且Hook难度减少。具体实施模式可分为为裸函数或内联汇编。裸函数形式,即为一个独立函数,其余函数通过传递零碎调用号和参数调用该函数内联汇编形式,会将SVC内联到每个调用函数中。这两者相比拟,各有劣势。裸函数形式,如果攻击者对此函数进行hook,能够很不便的通过内存校验检测出问题(如果间接用变量拜访这段内存,也是很容易逆向剖析,因而实际操作时能够应用一些间接援用技巧)。但无论如何,因为iOS上非越狱环境无奈动态创建并执行代码,因而SVC这条汇编指令肯定是存在于内存中,最常见的就是svc 0x80和svc 0x50(留神这个指令的立刻数是默认疏忽的,因而svc 0或者svc 0xffff成果都是一样的),对应机器码为01 10 00 D4,通常在逆向剖析时,间接搜此二进制即可中转检测的关键处。为了反抗svc指令的检测和批改,缓解的形式也很多,比方:将svc藏在非凡segment中结构出蕴含01 10 00 D4的有效指令机器码来进行混同。将函数拆分成多个8字节函数,也就是2条指令,从而防止被inlinehook,因为inlinehook至多须要3条(Substitute)或4条(Substrate)指令能力胜利 本文提出一种形式,能够更好的暗藏svc调用。libsystem_kernel.dylib是具体实现零碎调用的动静库,通过逆向能够发现其蕴含大量的svc指令,那取巧的方法就是获取到这里svc的地址,并包装成函数进行调用,即可神不知鬼不觉达到暗藏svc并进行零碎调用的目标。 _text:00000002382DA4AC EXPORT ___gettimeofday__text:00000002382DA4AC ___gettimeofday ; CODE XREF: _prepare_times_array_and_attrs+74↑p__text:00000002382DA4AC__text:00000002382DA4AC var_10 = -0x10__text:00000002382DA4AC__text:00000002382DA4AC 02 00 80 D2 MOV X2, #0__text:00000002382DA4B0 90 0E 80 D2 MOV X16, #0x74__text:00000002382DA4B4 01 10 00 D4 SVC 0x80__text:00000002382DA4B8 C3 00 00 54 B.CC locret_2382DA4D0__text:00000002382DA4BC FD 7B BF A9 STP X29, X30, [SP,#var_10]!__text:00000002382DA4C0 FD 03 00 91 MOV X29, SP__text:00000002382DA4C4 5E D9 FF 97 BL _cerror_nocancel__text:00000002382DA4C8 BF 03 00 91 MOV SP, X29__text:00000002382DA4CC FD 7B C1 A8 LDP X29, X30, [SP+0x10+var_10],#0x10__text:00000002382DA4D0__text:00000002382DA4D0 locret_2382DA4D0 ; CODE XREF: ___gettimeofday+C↑j__text:00000002382DA4D0 C0 03 5F D6 RET arm64上具体实现代码如下,此代码通过获取libsystem_kernel模块地址,并爆搜指令的形式获取svc,并实现裸函数和内联函数两种调用形式,通过逆向能够发现,程序中并没有svc指令,完满达到目标!: ...

July 8, 2022 · 2 min · jiezi

关于ios:RunLoop原理

【原英】https://developpaper.com/ios-... 在晓得Runloop之前一般来说,一个线程只能执行一个工作,执行完就会退出。当咱们须要让线程能够随时处理事件而不退出线程,咱们就要应用Runloop。它外部是一个do while循环,一直地解决各种工作,保障线程可能的间断运行。 Runloop的目标保障线程中有工作时能够执行线程工作。当线程中没有工作时,让线程休眠,进步程序性,节俭资源。 Runloop的作用简述详述放弃程序间断运行应用程序启动后,将启动主线程。当主线程启动时,会启动主线程对应该的runloop。Runloop能够保障线程不会被毁坏。如果主线程没有被销毁,程序将持续运行。解决应用程序中的各种事件事件响应、手势辨认、界面刷新、主动开释池、NSTimer等事件处理。节俭CPU资源,进步程序性当线程中有工作时,确保线程可能工作。当线程没有工作时,让线程休眠,进步程序性能,节俭资源。该做事的时候做事,该劳动的时候劳动。Runloop原理名称类型所在框架原子性NSRunloopNSObjectFundation线程不平安CFRunloopstructCoreFundation线程平安为了更好地了解Runloop,浏览源代码是一个不错的抉择。老司机说有了源码,runloop就不会那么神秘了。首先,咱们通常说runloop有两种。一个是NSRunloop,另一个是CFRunloop。那么让我先通过源码理解一下CFRunloop。首先,咱们看一下根本的数据结构 1.CFRunloop的定义。这里我正文了所有须要留神的参数 struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t _lock; /* locked for accessing mode list */ __CFPort _wakeUpPort; // used for CFRunLoopWakeUp 内核向该端口发送音讯能够唤醒runloop Boolean _unused; volatile _per_run_data *_perRunData; // reset for runs of the run loop pthread_t _pthread; //RunLoop对应的线程 uint32_t _winthread; CFMutableSetRef _commonModes; //存储的是字符串,记录所有标记为common的mode CFMutableSetRef _commonModeItems; //存储所有commonMode的item(source、timer、observer) CFRunLoopModeRef _currentMode; //以后运行的mode CFMutableSetRef _modes; //存储的是CFRunLoopModeRef struct _block_item *_blocks_head; //doblocks的时候用到 struct _block_item *_blocks_tail; CFTypeRef _counterpart;};能够看出CFRunloop是一个有很多属性的构造体。看一下这个构造中咱们须要留神的参数。每个runloop都有本人的mode,并且有不止一种mode,mode寄存着runloop要解决的事件源。事件源有3种,source、timer和observer。Runloop有很多模式,然而在某个工夫只能有一种特定的模式,即_currentMode。上面第二项形容的是runloop的模式,它与runloop构造体(mode)相干参数中的几个模式无关: 名称模式_currentMode以后的runloop模式_modes以后运行中的所有模式另外,runloop 中的一种模式是 NSRunloop 罕用模式。这种模式没有意义。它只是标记模式的汇合; ...

July 7, 2022 · 2 min · jiezi

关于ios:iOS-AR研究

iOS AR钻研从技术层面上讲,ARKit通过整合了AVFoundation、CoreMotion、CoreML3个框架,在这个根底上整合扩大而成。其中,AVFoundation是解决基于工夫的多媒体数据框架,如前后摄像头、声音等。CoreMotion是解决减速计、陀螺仪、LiDAR等传感器数据信息框架,如以后设施的地位、程度旋转、静止速度、事实物体扫描等。CoreML则是机器学习框架,外部集成大量的算法,如计算机图片解决与人脸识别等。ARKit能做什么表列形容特色点检测检测并跟踪从摄像头采集图像中的特色点信息,并利用这些特色点构建对事实啊不理我的了解立体检测检测并跟踪事实世界中的平坦外表,ARKi反对立体与垂直立体检测图片检测辨认跟踪检测辨认并跟踪预扫描的2D图像,ARKit最大反对同时检测100张图像3D物体检测跟踪检测辨认并跟踪预扫描的3D物体光照预计利用从摄像头图片采集的光照信息估计环境中的光照,并依此调整虚构物体的光照成果环境光反射利用从摄像头图像中采集的信息生成环境光探头,并利用这些图片信息反射实在环境中的物体,以达到更实在的渲染成果世界地图反对保留与加载世界空间的空间映射数据 。以便在不同设施之间共享体验。人脸检测跟踪检测跟踪摄像头图片中的人脸,ARKit反对同时跟踪3张人脸,ARKit还反对眼动与舌动跟踪,并反对人脸BlendShape性能,能够驱动虚拟人像模型。射线检测人设施屏幕发射线虚构对象或者立体。人体动作捕获检测跟踪摄像头图像中的人形,捕捉人形动作,并用人形动作驱动虚构模型。ARKit反对2D和3D人形捕获跟踪。人形遮挡分享摄像头图像中的人形区域,并能预计人形区域深度,以实现与虚构物体的深度比照,从两颗实现正确的遮挡关系。多人合作多设施音实时通信经共享AR体验同时开启前后摄像头容许同时开启设施前后摄像头,并可利用前置摄像头采集到的人脸检测数据驱动后置摄像头中的模型。3D音效模仿实在空间中的3D声音流传成果景深模仿照相机采集图像信息时的景深成果,实现售点转移相机噪声模仿照相机采集图像时呈现 的不规则 噪声静止含糊模仿摄像机在拍摄静止物体时呈现 的含糊拖尾景象自定义渲染反对对所有ARKit个性的自定义渲染场景几何应用LiDAR实时捕捉场景深度信息并转化为场景几何网格场景深度应用LiDAR实时捕捉场景深度信息视频纹理采纳视频图像作为纹理,能够实现视频播放,动静纹理性能地理位置锚点利用GPS与地图在特定的地理位置上搁置虚构物体ARKit有两种配置模式名称形容ARWorldTrackingConfiguration应用后置摄像以6DOF的模式开启静止跟踪ARFaceTrackingConfiguration应用设施的前置摄像头检测跟踪人脸ARKit的三大根底能力: 名称形容ARSession一个AR程序只有有一个ARSession,ARKit所有的会话都建设在ARSession根底之上ARAnchor锚点,在ARKit的世界中,所有虚构物体都是由锚点组成。通过摄像头捕捉的图像中,计算出以后场景的锚点地位信息、深度等信息ARFrameAR帧,是摄像头获取到的一帧图像,ARKit背景渲染都是由这个图像帧实现。信息包含:光照、锚点数量、世界地图状态、以后场景的参数、点云、旋转、工夫、视矩阵等信息。渲染ARKit自身并不间接提供渲染性能,AR场景渲染能够抉择第三方框架进行渲染,苹果目前提供的渲染框架有:SceneKit、SpriteKit、Metal或自定义渲染框架。苹果尽管提供了多个第三渲染框架,但这些渲染框架并不是为AR利用开而设计的。如:SceneKit设计解决3D渲染、SpriteKit设计解决2D渲染、Metal则是更底层的图形API。在2019年,苹果公司应用Swift语言全新开发了RealityKit渲染框架,其重点解决的问题是在事实环境中的虚构元素PBR渲染及精准的行为模仿,包含物理仿真、环境反射、环境光预计等。也就是说RealityKit是专为实在环境中虚构元素做渲染而设计的,次要目标是为了使虚构物体在事实世界中营造更强的真实感。 目前我通过ARKit获取到的数据在ARKit的会话中,ARKit启动后会主动进行检测环境,我应用的是ARWorldTrackingConfiguration和[.sceneDepth, .smoothedSceneDepth]的配置进行会话,通过ARSCNView来进行显示。在ARKit的会话中能够失去didAdd:[ARAnchor]、didUpdate:[ARAnchor]、didUpdate:ARFrame、didRemove:[ARAnchor]等多实时数据。我通过didUpdate:ARFrame获取以后帧,代码我就不贴上来了,我列一下我目前获取到的数据,这个数据结构蕴含以下信息 名称形容timestamp以后帧的工夫截capturedImage以后帧,是CVPixelBuffer数据结构,能够转成CGImage或UIImage,再转成PNG或JPG图片cameraGrainTexture属于MTLTexture类型数据cameraGrainIntensity属于Float类型数据capturedDepthData帧捕捉到的深度数据。属于AVDepthData类型数据capturedDepthDataTimestamp标识深度数据的工夫戳。camera属于ARCamera类型数据anchors以后帧的场景中的锚点,是一个数组[ARAnchor]lightEstimate用来捕获框架图像的相机。是ARLightEstimate数据结构,蕴含ambientIntensity(照明的环境强度。),ambientColorTemperature(照明的环境色温。)rawFeaturePoints场景中绝对于帧原点的特色点,俗称点云。是ARPointCloud数据结构,蕴含了points(组成点云的三维点。)、identifiers惟一标识worldMappingStatus世界地图获取状态,是一个枚举值:notAvailable、limited、extending、mappedsegmentationBuffer一个示意capturedImage分段内容的缓冲区。estimatedDepthData示意执行的宰割的预计深度值的缓冲区。detectedBody在以后帧中检测到的物体。是ARBody2D数据结构,蕴含了一个ARSkeleton2D数据类型的skeletongeoTrackingStatus天文跟踪的状态。sceneDepth深度数据。是ARDepthData数据结构,蕴含了depthMap一个像素缓冲区,蕴含每个像素的深度数据(以米为单位)、confidenceMap一个像素缓冲区,蕴含' depthMap '中每个深度值的相信级别。smoothedSceneDepth场景深度数据,平滑的工夫一致性。是ARDepthData数据结构

July 7, 2022 · 1 min · jiezi

关于ios:只是巧合苹果iOS16的神秘技术竟然与中国企业5年前产品一致

最近,苹果又来“整顿”手机厂商了。 有传言称,新版 iOS 16 将退出一个名为「主动验证」的新性能,可跳过网页和 App 中的人机验证流程,降级了 iOS 16 测试版的用户,能够进入「设置」—「Apple ID」—「明码与安全性」,在页面最下方找到这个性能。 什么意思呢? 以前,当你关上苹果的某个 App 时,零碎首先要证实你是“人”而不是“机器”,须要辨认验证码来证实你是你,通过了就证实你是能够被信赖的。当初,苹果为用户间接略过了验证码这一环节,也就是说,苹果抢先一步通过算法证实了你是你。 对于这一更新,不少果粉直呼:“真的太兽性了”。 无感验证将是将来新趋势 那么,苹果是如何实现绕过“验证码”的呢? 答案就是苹果使用了一种全新、凋谢的验证机制 —— 私密证实令牌 (Private Access Tokens,缩写为 PAT)。 PAT 并不指代某一种技术或某一种服务,而是一个验证用户的协定。它须要 Client、Mediator、Issuer 和 Origin 参加,能力实现整个验证,如下图: 这次主动验证是苹果与云服务商 Cloudflare 单干实现的,实现过程如下 (以用户应用浏览器拜访某个网站的场景为例): 整个流程蕴含四个模块,即浏览器、苹果手机零碎、云服务商 Cloudflare,网站后盾; 其中网站后盾需部署在 Cloudflare 上。 首先,用户应用浏览器拜访网站时,因网站后盾部署在 Cloudflare 上,Cloudflare 会要求浏览器必须携带 token。 紧接着,浏览器会调用苹果零碎服务进行检测,零碎服务会检测以后设施的合法性,是否是可信设施,查看通过后会告诉 Cloudflare,Cloudflare 下发 token 给到浏览器。 最初,浏览器携带 token 拜访网站 (Origin),云服务商 Cloudflare 做网关代理,作为 Origin 角色来验证 token 的有效性,放行拜访网站。 看起来如同很简单,但整个流程的重点有两个: 一是整个验证流程没有任何须要人工染指的验证过程 (输出字符或点击图片等),整个校验过程根本无需客户端和服务端做革新,由苹果设施和云服务供应商实现,设施是否可信的判断由苹果零碎实现,相比三方 SDK,苹果零碎有能力获取到更多的信息,做更全面的判断。另外,该技术能够显著晋升脱离浏览器应用脚本间接爬取数据的爬虫老本; 二是证实「我是人」的形式也从答题、隐衷让渡,变成更正当的查看设施是否被破解等信息,应用反对 PAT 协定的设施和网站,会缩小验证码的弹出,用户体验会更好。 ...

July 1, 2022 · 1 min · jiezi

关于ios:百度直播iOS-SDK平台化输出改造

导读:百度直播定位成直播SDK,赋能百度厂内APP应用,随着业务规模疾速扩充、代码体量收缩、宿主接入定制诉求强烈,在不影响业务迭代和业务规模扩张的前提下,直播工程架构也在不停优化。 全文2496字,预计浏览工夫7分钟。 一、背景百度直播定位成直播SDK, 赋能百度厂内APP应用, 随着业务规模疾速扩充、代码体量收缩, 直播原有工程结构限制了直播的疾速倒退, 随着垂类APP数量接入, 宿主接入流程中定制艰难/配置调试耗时/须要实现的协定多等问题制约了SDK对外的输入, 总结起来就是以下两个大类问题: 工程层面问题: 原生工程构造影响开发效率/业务代码耦合重大/宿主绑定的性能宏定义造成SDK差异化输入艰难接入流程层面问题: 定制艰难/配置调试耗时/协定泛滥等问题在不影响业务迭代和业务规模扩张的前提下, 直播团团队有针对性的逐渐进行了革新, 实现最终SDK灵便高效的平台化输入。 二、工程层面革新工程层面革新分为三步走, 首先是工程接入EasyBox, 其次是业务维度组件化多仓库拆分, 在前两步根底上最初欠缺SDK差异化输入能力, 整体实现了工程架构革新迁徙。 1.工程革新直播最晚期工程是基于Xcode原生工程, 多project嵌套连编实现工程构件, 这种形式在弊病太多, 基于手百自研EasyBox工具链, 直播进行了工程化的革新, EasyBox工具链对于工程是标准化的模版式革新 首先是对于liveBoxAPP工程的壳化, 其次对于原有的业务工程规范分层, 直播工程从新划分了逻辑层级: 壳工程, 直播SDK编译运行构建环境MixTure构建层, 管制SDK差异化构建,通过EasyBox反对变体(variant)组件的实现差异化, 通过link\_dependency管制产物SDK的自由组合生成业务层, 直播外围业务根底库层宿主平台库依赖层/三方依赖库 基于以上革新, 使直播工程依赖关系更加清晰, Easybox分层使层级之间的依赖不会裂化, 以上革新只是基于直播原用工程构造的降级革新, 业务仓库自身还是有问题, 因而针对业务仓库做了多仓多组件模版拆分。 2.多仓多组件模版拆分业务仓库的问题次要是业务耦合重大/权限无隔离, 直播晚期仓库管理机制是Monorepo, 随着业务规模收缩, 团队扩充, 直播依照模版业务唯独拆分了多仓库, 仓库治理降级到Multirepo, easyBox自身也反对Multirepo模式. 直播间业务VC是由一套slotPage框架来治理布局和服务, slotPage简略来说就是把直播间的UI和能力划分为(直播间内)组件/插件/服务, 提供组件的布局治理/事件散发/根底状态治理的一套页面管理机制, 直播针对business层仓库组件进行了模版维度的拆分, 具体分为已下几步: Business层拆分出service层, 将通用能力对立下沉到service层仓库组件拆分根底外围直播容器组件, 提供直播间外围能力拆分直播间性能积淀为通用组件插件池依照模版维度拆分Business层仓库组件, 归属业务模版特有的(直播间内)组件/插件 3. 反对SDK差异化输入不同宿主对SDK定制需要差异化很大, 因而SDK要灵便反对裁剪, EasyBox尽管能通过变体(variant)和link\_dependency能实现差异化构建, 然而对于直播间内小组件性能裁剪定制不太实用, ,因而直播提供小组件编译时注入能力, 直播组件都蕴含一个注册module, module散发直播外围的Module Event, 在event适合的机会, 注册组件的服务到Pyramid, 采纳实现impl和interface拆散的形式来实现真正的须要差异化输入组件的编译隔离, 差异化组件横向禁止依赖, impl组件只能依赖interface的接口组件。 ...

June 30, 2022 · 1 min · jiezi

关于ios:Swift-Talk理解值类型

咱们应用写时复制 copy on write 的思维,对 NSMutableData 进行封装,以此来了解咱们的规范库的实现形式。 规范库中提供的所有的根本汇合类型都是值类型,通过写时复制的思维保障了他的高效性。汇合类型是咱们比拟罕用到的数据类型,所以理解他的性能个性很重要,咱们来一起看一下写时复制是如何工作的,并且尝试本人手动实现一个。 援用类型举个例子,咱们比拟一下Swift的Data(构造体)和Foundation库中的NSMutableData(类)。首先咱们应用一些字节数据来初始化 NSMutableData 实例。 var sampleBytes: [UInt8] = [0x0b,0xad,0xf0,0x0d]let nsData = NSMutableData(bytes: sampleBytes, length: sampleBytes.count)咱们应用了 let 来申明 nsData,然而像 NSMutableData 这样的援用类型不受let/var 的管制。对于援用类型来说,用 let 申明代表 nsData 这个指针不能在指向别的内存,然而他指向的这个内存中的数据是能够变动的。也就是说咱们仍然能够往 nsData 中 append 数据。 nsData.append(sampleBytes, length: sampleBytes.count)当咱们再申明一个对象,扭转其中一个对象,另一个对象也会发生变化。 let nsOtherData = nsDatansData.append(sampleBytes, length: sampleBytes.count)// nsOtherData 也会变如果咱们想产生一个独立的正本,咱们须要应用 mutableCopy(返回一个 Any 类型),咱们须要把返回值强转成咱们须要的 NSMutableData 类型。 let nsOtherData = nsData.mutableCopy() as! NSMutableDatansData.append(sampleBytes, length: sampleBytes.count)// nsOtherData 不变值类型首先咱们也是通过 sampleBytes 来初始化一个 Data。 let data = Data(bytes: sampleBytes, count: sampleBytes.count)如果咱们应用 let 关键字,那编译器就不会容许咱们调用类型 append 这样的办法。所以如果要扭转 data 的值,要应用 var 。 ...

June 30, 2022 · 2 min · jiezi

关于ios:杂谈iOS马甲包

什么是马甲包马甲包个别是主APP的分身或者克隆,也或者说是衣着马甲的一个APP,脱掉马甲,APP将出现另一种款式,也就是常说的AB面APP。 1、主APP的分身或者克隆类型的马甲包先说第一种就是主APP的分身或者克隆,当初很公司个别有一个本人的主产品,然而也会去做一些和主APP相似的阉割版的APP,我的项目代码也基本上齐全复用,app的利用名称、副标题、icon、利用截图、包名、关键词和开发者账号都与主app不一样,其余基本一致,比方下图:为什么要这样做呢?这样做又有什么益处呢? a、躲避市场或者政策危险用于app刷量、冲榜、刷词、刷热搜、躲避账号限度、防下架应急措施、竞品竞争等,抵制主包危险。 b、抢占利用市场无限地位关键词搜寻后果占位、榜单占位、笼罩更多关键词等。 c、导量马甲包自身是能够获取新增用户的,其能够通过与主App后盾信息共享、弹窗或者推送的模式疏导用户下载主App等形式向主App导量。 d、测试大范畴改版等的成果,升高危险马甲包的益处是大范畴改版之后能够上线验证成果,一旦引发不良影响又不会造成很大的损失。如果测试成果良好,则能够对主App进行相应性能迭代。 2、AB面APP类型的马甲包这种类型的APP个别是在审核的时候,把A面出现给apple的审核人员,审核完结当前再把B面出现给用户;这种个别是为了躲避苹果严格刻薄的审核限度而呈现的一种产业;这种的利用很常见,不论是小作坊APP还是大厂的APP,基本上都会搞;比方为了躲避苹果的30% 的抽成领取,在审核的时候暗藏虚构充值入口,上线胜利当前再开发充值入口,等等; 马甲包的审核危险(Apple审核 4.3)Apple审核大体分为三局部,预审、机审和人工审核。包上传后首先进入的是预审,会被扫描API等,没问题的话才会在iTC里呈现,而后才能够提交至 Waiting。在审核后期,也就是 Waiting For Review(期待审核)阶段个别是机审。机审不通过则间接被拒,通过后会进入人工审核,即In Review(审核)阶段,这个阶段次要看的是App的元数据,例如题目、形容、截图等,以及检测App的性能应用状况,常遇到的ipv6也在此处检测。 4.3是性能或者应用程序反复呈现在App Store,包含雷同类型产品性能较统一,以及上传马甲或者分包导致的被拒回复,以下计划心愿能帮到大家解决此类问题! 发件人 Apple4. 3 Design: SpamGuideline 4.3 - Design - SpamYour app duplicates the content and functionality of apps submitted to the App Store, which is considered a form of spam.Apps that simply duplicate content or functionality create clutter, diminish the overall experience for the end user, and reduce the ability of developers to market their apps.(机器审核)发件人 Apple4. 3 Design: SpamGuideline 4.3 - Design - SpamWe found that your app provides the same feature set as other apps submitted to the App Store, which is not appropriate to theApp Store.(人工审核)解决方案只有做的是对我的项目的差别解决,个别次要是以下几点: ...

June 23, 2022 · 1 min · jiezi

关于ios:ZFJObsLibiOS代码混淆工具马甲包混淆工具Python脚本混淆iOS工程

ZFJObsLib更新阐明 https://gitee.com/zfj1128/ZFJ... ----------------------------------------分割线---------------------------------------- 前言 明天次要想说的是iOS的代码混同,为什么想做代码混同?为了APP的平安,为了避免他人破壳轻易破解咱们代码;还有就是做马甲包了,咱们晓得马甲包的市场需求很大,然而不能破费过多的精力在开发上,毕竟只是个马甲,没必要破费太多的老本! 混同工具 网上搜了一下,开源收费的混同都在转载念茜大姐大的sh脚本的混同办法,或者在念茜的脚本根底上二次开发,大家去看过就晓得念茜的这篇博客是在14年写的,那时我刚做iOS没多久?,而且那时候中国区审核还没有那么严格,若果你当初还应用那种办法进行混同,你必定会收到苹果的2.3.1 大礼包?,所以咱们还是摸索别的混同办法吧,不要再挖坟了! ZFJObsLib次要是通过Python写的混同工具,具体性能有办法混同、属性混同、类名混同、增加垃圾代码、主动创立垃圾类、删除正文、批改资源文件Hash值、加密字符串、翻新资源名、模仿人工混同、混同文件名、混同文件目录、混同词库、混同日志、映射列表、敏感词过滤、图片压缩、爬虫服务、批改我的项目名、翻新我的项目UUID、主动备份混同我的项目、自定义疏忽属性、自定义疏忽函数、自定义疏忽类名、界面色彩魔改,具体的如下: 软件界面 ZFJObsLib混同工具全面反对OC与Swift语言开发的我的项目!!! 下载地址: Gitee:https://gitee.com/zfj1128/ZFJ... GitHub:https://github.com/zfjsyqk/ZF... 应用教学视频: 链接:https://pan.baidu.com/s/1pqUk... 明码:9sll ZFJObsLib软件的次要界面如下: 混同日志 进行混同的局部日志,混同的时候会主动生成混同日志《ZFJ混同日志.log》,便于开发者批改局部报错,在混同界面下方的《关上混同日志》按钮关上: 疏忽门路 咱们在混同的时候,没必要全副进行混同,特地是第三方库,或者Pods治理的第三方库;毕竟混同的越多问题也就越多和也越费时,所以我增加了混同疏忽文件和疏忽文件性能,如下图: 特地阐明:多级目录混同状况,如果想疏忽的目录在多个文件夹中有重名的,比方你想疏忽Home上面的Models文件夹,然而在Home文件夹和Mine文件夹都有个Models文件夹,你能够这样设置'Home/Models'就OK了!So Easy!☝️☝️☝️ 如果想过滤领有雷同前缀的类,比方ZFJ_TouchClass.h/ZFJ_TouchClass.m/ZFJ_MyButton.h/ZFJ_MyButton.m,能够设置‘ZFJ_+’就能够对以‘ZFJ_’结尾的类进行过滤疏忽; 如果想过滤领有雷同后缀的类,比方ZFJName.h/ZFJName.m/ABCName.h/ABCName.h,能够设置‘+Name’就能够对以‘Name’结尾的类进行过滤疏忽。 应用问答 在应用的时候要是有什么问题,能够先看看《ZFJObsLib-iOS代码混同软件应用问答(Q&A)》 在软件能够在零碎栏-帮忙-应用问答查看,如下图: 软件性能 ✍️✍️✍️ZFJObsLib有很多性能,大家能够依据本人的理论应用状况自行抉择!✍️✍️✍️ 在此附上一些过包大佬罕用的性能截图,仅供参考,这些大佬最牛逼的一周过了五六个: 1.办法混同 如果混同了零碎的办法,能够在办法过滤外面手动增加须要过滤的办法,自己也统计了上百个常见的零碎办法,然而必定不能统计全面笼罩,所以如果遇到没有笼罩的用户能够手动增加设置!办法过滤性能在主菜单首页! 2.属性混同 如果你的命名和零碎属性雷同,导致系统属性被混同,比方属性字段title和零碎的一些控件的title始终,所以在混同的过程中会把零碎的属性给混同了,导致报错,同样你能够再属性过滤中增加属性字段title(我曾经增加好title这个字段了),所以你遇到其余的状况你能够本人增加! 3.类名混同 类名混同也会导致一些和零碎反复,比方你的类名命名为‘TabBarController’,然而在零碎中有一个UITabBarController,所以在类名混同的时候就会导致混同出错,通样你能够应用类名过滤的性能,当然个别类名混同基本上是没错的! 4.增加垃圾代码 在.h文件中裸露垃圾代码 垃圾代码的调用与实现 5.创立垃圾类 具体请看:?《Python-ZFJObsLib完满生成iOS垃圾代码》https://zfj1128.blog.csdn.net... 6.删除正文 7.敏感词过滤 过滤博彩类敏感词 8.批改Hash值 针对我的项目中的资源文件,咱们能够通过批改Hash的形式来进行混同,运行如下: 9.加密字符串 编译前的代码如下: 编译后的代码如下: 加密混同反编译前后Hopper比照如下: 咱们能够看到再通过Hopper看不到硬编码了!??? 10.翻新资源名 找到工程中的图片资源并翻新,而后主动替换代码中的援用。 这里如果有图片加载不进去的状况,很大可能是你在代码中援用图片名是采纳字符串拼接的形式,导致资源文件被批改了,然而代码中找不到无奈批改的状况! 11.混同工程目录 为了保障目录混同的准确性,倡议把我的项目中空的目录都给删了;还有一种状况就是没有援用的文件夹也要删了,比方本地有这个目录然而我的项目没有援用! 12.设置混同前缀 阐明:设置混同前缀,肯定要点击保留哦!!!✌️✌️✌️还有就是能够设置办法混同的后缀,如果不设置默认是Fun! 属性混同、类名混同和办法混同反对只加前缀不批改原来名字的性能,只须要在设置的前缀前面加上‘#’就OK了,如下图: 13.混同词库 ZFJObsLib自带二十多万的字典词库,所以不必放心代码反复问题;如果你感觉获得词库单词目标性不强或者无意思,你能够自定义词库,自定义词库解学视频如下: 链接:https://pan.baidu.com/s/1iBc1... 明码:wadz 还能够通过读取混同词库来读取其余我的项目的词库来混同本人的我的项目,在混同界面的零碎栏-设置-词库抉择-读取词库; 14.读取UUID性能 / 翻新我的项目UUID性能 ...

June 23, 2022 · 1 min · jiezi

关于ios:APP细说APP网络深度优化与网络安全

前言说到APP优化,咱们也能够从很多方面进行优化,从包大小、页面晦涩度、内存占用、数据缓存、网络数据安全等等来优化加固咱们的APP,每一个点开展又有很多须要将的,我以前也专门写了一篇对于APP性能优化的博文,如下:《iOS-性能优化的那些事》在挪动端APP网络优化也是APP性能优化的一个十分重要的一个点,而且99.99%的APP都会随同着网络交互;在此,我将对APP网络优化和网络安全做一个具体的总结,次要从流量、品质、平安方面去说,如要构造点如下: 流量耗费先说一个亲身经历过得事件,以前在一家公司开发了一款APP,有一点客服反馈有个上海老大爷打电话过去骂人,手机装了咱们的APP,一个早晨用掉人家一两个G;起初公司也被动帮人家承当了这部分的流量资费,要害是15年流量资费还很高的,这个APP当然不是我写的,是安卓的小伙伴!即便流量当初价格不是很贵了,然而尽可能的帮用户节俭漂泊也是十分应该的! 检测流量耗费置信大家在开发APP的时候必定会做一些埋点和日志上报的性能,咱们也能够把网络申请的监控也做进去,咱们能够检测用户在一段时间内的流量耗费,计算流量的均值和峰值等等,并上报流量接口,这些咱们在日志或者埋点零碎外面都能够记录,而后上传给服务端,而后进行数据分析,找出流量耗费的不足之处。 数据缓存说到缓存,这也是一个十分大的一个点,有工夫也能够开展说,我平时的博客对于缓存也讲到很多,缓存的一个十分重要的益处就是提好了页面加载速度,进步用户的应用体验;然而缓存也能够替用户节俭流量的耗费。APP数据的缓存无非是列表接口的缓存、WebView的缓存,对于WebView的缓存我也独自写过,如下:《iOS-WKWebView缓存并保障实时性》《iOS-UIWebView缓存并保障实时性》咱们还能够做资源包下发预制加载等,这里也不开展了! 数据压缩对于数据压缩,这边次要想讲的就是资源文件的数据压缩了,次要在网络上传和网络下载方面; 1.数据上传比方上传图片数据的时候是不是须要原图高清图,当初相机的像素都高,咱们是不是能够搞了压缩一下图片或者视频再上传,就像微信发送图片的时候,用户能够抉择压缩或者原图; 2.数据下载下载目前也是APP的大头了,个别APP都是申请下载的数据比拟多;咱们在加载资源的时候能够抉择加载压缩资源,比方微信的朋友圈,小图的时候咱们能够加载缩略图,要是点击查看大图的时候才思考加载大图原图; 交互频率数据交互如果比拟频繁会耗费用户的流量,而且用户体验不好,还有一个十分重要的起因就是频繁的网络申请也会比拟损耗手机的电量;所以咱们能够合并一些能合并的网络申请,比方日志上报的时候。 申请开释在APP开发的过程中,个别就是一进入页面就进行网络申请,而后期待完结加载数据,然而比方网络申请比拟迟缓(可能是数据量比拟大,也有可能是网络情况不好),用户不想等了,间接返回页面销毁了,然而咱们的大部分网络申请是独自封装的,然而网络申请还在持续申请中,这里数据、性能、内存、电量的问题就进去了,所以大家在封装网络申请的时候要把页面销毁就勾销网络申请的场景思考进去! 网络品质申请速度网络申请的速度是影响用户体验的一个十分重要的起因,所以服务端也要想着来进步api的交互速度,为此咱们能够通过上面的几个计划来优化交互速度,如下:a.域名合并,缩小了DNS调用次数,升高了DNS劫持危险;b.ip直连,去除DNS的解析步骤;c.api缓存,比方redis缓存;d.数据资源压缩上传; 申请品质监控网络申请品质和申请速度,而后记录日志进行上报,监控残缺的网络申请链路; 服务器压力api的设计也要思考到api的压力以及服务器的压力,避免因为压力太大导致接口挂掉,从而影响用户的体验; 数据处理服务端在给APP端提供数据的时候,防止让APP端进行数据处理或者运算,比拟APP的内存资源和运算资源无限,不要适度耗费节约APP资源;比方,我上家公司的用户信息外面有用户的年龄,然而服务端给的不是间接的年龄数据,而是给的生日工夫戳,须要APP端本人去计算年龄,然而咱们晓得NSDateFormatter又是重大内存开销对象,在列表解决的时候又比拟耗费内存,所以倡议对于运算的一些货色最好在服务端计算好,这种不仅仅保障APP的性能问题,还是一种平安问题! 网络安全咱们在APP端的网络安全问题个别是APP抓包、DNS劫持、服务器平安,具体如下: APP抓包说到抓包,侵入者能够抉择抓取数据来窃密APP的要害数据,而后模仿申请,做一些APP不好管制的事件,在此咱们能够应用Https进行网络申请,还能够禁止网络申请设置代码;还能够把申请头和申请体进行加密传输,多一次保障!然而须要阐明一点的是,没用相对的平安,只有是人设计的加密就有人设计解密,窥视心里在作怪! DNS劫持DNS劫持,因为域名解析为IP这个过程中,其解析是基于UDP 协定实现,所以报文是明文状态,可能会在申请过程中被监测,而后攻击者做一些本人的解决,比方返回假的IP地址或者什么都不做使申请失去响应,其成果就是对特定的网络不能反馈或拜访的是假网址。根本原因就是以下两点:a.歹意攻打,拦挡运营商的解析过程,把本人的非法货色嵌入其中。b.运营商为了利益或者一些其余的因素,容许一些第三方在本人的链接里打打广告之类的。如何避免DNS劫持?能够通过下面我说的IP直连,本人在APP解析!举荐一篇写的比拟具体的对于DNS的,如下:《APP网络优化之DNS优化实际》 服务器平安服务器平安能够从物理平安和网络安全来说a.物理平安,服务器要思考比方断电、断网等状况下导致的平安问题;b.网络安全,避免服务器被攻打、被爬虫等问题;所以,服务器的备份机制和数据备份机制和重要,还要限度同一IP的申请次数和距离等; 结束语如有不足之处还望各位大佬不吝赐教,也欢送大家加群或者叫我QQ探讨交流学习!

June 23, 2022 · 1 min · jiezi

关于ios:Swift-Learning-Summary-Advanced-Operators

Advanced OperatorsUnlike arithmetic operators in C, arithmetic operators in Swift don’t overflow by default. If want to overflow by default, use the overflow operation begin with ampersand (&). For example, the overflow addition operator (&+). It’s so free to define custom infix, prefix, postfix and assignment operators, precedence and associativity values. Bitwise OperatorsHere we use a function to pad 0 for the number’s print result. func pad(num: UInt8, count: Int) -> String { var str = String(num, radix: 2) var res: String = str for _ in 0..<(count - str.count) { res = "0" + res } return res }~ NOT ...

June 19, 2022 · 8 min · jiezi

关于ios:大量模块壳工程本地如何快速编译优酷-iOS-工程插件化实践

作者:醉仙 随着优酷业务的疾速倒退,随之而来的是模块数量的爆发式增长,根本每年以大量新增模块的速度减少,到目前为止优酷曾经有十分宏大的模块依赖。模块之间通信往往是互相间接依赖调用,以至于耦合非常重大且凌乱,每一个库依赖都是一颗“树”,甚至于一张“网”,对日常研发造成很多困扰: 插件化落地后果iOS模块插件化曾经全面在优酷落地,积淀出各业务线的轻量工程,大量的业务及架构插件,后续可依据不同业务需要,自在组装插件工程。以下是目前插件化工程落地后的一些收益: 间接收益 业务插件工程编译效率晋升 显著,本地编译工夫大幅升高,相干全副开发已应用起来;通过插件组装生成业务插件工程,插件工程反对模拟器编译调试,并反对热重载;模块工程和整包工程均应用插件作为依赖,彻底解决模块工程和整包工程依赖模块版本不统一状况,并反对依赖模块版本自动更新;业务插件工程依赖库数量大幅缩小,且pod间接复用缓存,大幅晋升pod成功率及速度,磁盘占用大幅缩小;间接收益 可提供运行内存、app启动、功耗等插件卡口,常态化保持良好的用户体验;所有插件反对自在组装,通过配置核心,提供疾速孵化极速版、国际版、Apple Watch、Apple TV等App的能力;依赖缩小,swift断点调试时的module树疾速生成,断点效率晋升;提速打包效率,建设插件工程构建平台,测试同学应用平台动静配置生成插件组合安装包即可进行测试。插件是什么插件是由一组模块聚合而成,同时也可依赖其余插件。在物理上,插件是一个文本形容文件,形容其蕴含的模块和插件信息;插件基于Xcode工程,可独立编译并生成App产物,反对多插件自由组合。简略插件 一个简略的插件能够仅由一个模块组成。 # 图片库插件target 'Plugin' do #模块A pod '模块A','5.9.4' end简单插件 一个简单插件能够由一个或多个插件和模块组成。 # 插件target 'Plugin' do # 图片库插件 plug '1.图片库插件' #webp图片解析模块 pod '模块B','0.1.4' #webp根底模块 pod '模块C','1.1.0.1' end为什么须要插件和多个业务团队同学沟通后,咱们发现大部分的业务在性能调试时,往往只关注波及到本人须要迭代的业务性能,对于其余业务并不关怀。于是咱们想到能够基于整包工程,裁剪出一个只有单业务性能的APP,这样编译速度必定会有极大的晋升。 裁剪APP须要对模块进行解耦,如果按模块颗粒度进行解耦,巨量模块进行解耦人力老本过高,而且过大的改变也会对线上稳定性有较大的影响。于是咱们对解耦粒度进行了放大,从模块解耦粒度放大到以插件为粒度进行解耦,这样咱们只须要解耦插件和插件之间的横向耦合关系,插件容许向下依赖其余插件,且插件外部模块也容许互相耦合,这样极大的的升高解耦的人力老本,也不便后续以插件维度进行依赖关系进行保护。 插件应用标准插件聚合准则 业务插件:业务模块按业务性能维度划分边界,聚合成业务插件;通用业务插件:通用业务模块按业务可复用最小集划分边界,聚合成通用业务插件;架构性能插件:团体中间件模块、优酷中间件模块,按性能最小集划分边界,聚合成架构性能插件。插件依赖准则 业务插件不容许横向依赖其余业务插件,容许依赖上层插件;架构层插件不容许依赖下层插件,容许依赖上层插件及其他架构插件。 模块归属准则 一个模块仅能归属到一个插件,须要明确模块的职能;同一个模块被多个插件依赖,须要思考下沉该模块为插件;一个模块能够写成一个插件。插件版本准则 每个插件没有版本的概念;一个集成区的模块和版本对应一套插件中的模块和版本;一套插件中的模块和版本默认和线上版本的集成区统一,也可设置并同步到最新集成区或历史集成区。插件层级大图基于以上插件的概念和应用标准,咱们对优酷APP架构进行插件化革新,从团体中间件到业务层,自下而上解耦聚合模块造成插件,最终积淀了大量插件和如下层级的APP架构。 业务实现层:对优酷现有的业务进行插件化革新,聚合成多个通用业务插件,通过业务插件和其依赖的通用业务插件、架构性能插件等大量插件,能疾速组合出一个轻量级业务APP,用于晋升业务Pod速度和开发调试速度;业务接口层:对优酷现有的业务进行横向解耦,造成多个业务接口插件,撑持下层业务插件横向解耦;通用业务插件:通用业务模块按业务可复用最小集划分边界,聚合成通用业务插件;架构性能插件:团体中间件模块、优酷中间件模块,按性能最小集划分边界,聚合成架构性能插件。低成本管控计划优酷所有模块曾经实现插件化革新,为了保障在后续版本迭代过程中,避免工程腐化,制订了一套低成本管控计划,能够自动更新插件内容,管控插件依赖关系。 插件自动更新插件内容次要包含模块名称和模块版本号,每次版本迭代,插件都面临插件中模块的新增、删除、名称变更、版本变更等问题,优酷每个版本集成大量的模块,如果全副人工手动保护,老本将十分微小,所以咱们部署了一套主动同步及巡检服务,次要有以下目标: 插件中新增、删除模块自动更新;插件中的模块版本号主动变更;插件内容更新实现主动对所有插件进行编译巡检;如果巡逻通过,插件合并到插件工程集成分支提供给业务插件工程应用;如果巡逻失败,钉钉告诉失败信息(失败插件名称、编译失败日志链接、插件新增模块提醒)到钉钉群,不便疾速排查问题。 插件依赖管控咱们基于插件的归属和层级,形象出规范的模块依赖关系数据,而后在模块构建打包时,减少依赖检测卡口,在每次模块构建过程中,执行依赖检测卡口,只有通过依赖检测的插件能力打包通过。 后果数据出现构建提效业务插件工程本地编译效率比照整包工程: 本地编译效率失去极大的晋升,均匀提效显著,本地编译工夫大幅升高,相干全副开发已应用起来。计算公式: 编译提效公式:本地编译提效 = (整包工程构建时长 - 业务插件工程构建时长) / 整包工程构建时长节约工夫公式:每月节约编译工夫(8小时工作日) = 插件工程月编译次数 均匀单次编译节约工夫(秒) / (60 60 * 8) 模拟器反对优酷存在局部模块不反对模拟器,导致优酷整包不反对模拟器,插件化革新后,业务在通过插件组装本人业务调试工程的时候,剔除这部分不反对模拟器的插件,使得业务插件工程能够应用模拟器进行调试。模拟器劣势: 一个企业号真机调试限度100台设施,而模拟器无限度;模拟器反对所有iOS零碎,针对一些旧零碎开发和测试成本低;模拟器反对热重载,无需编译和从新运行,批改代码保留即失效;提前适配iOS新机型UI。 磁盘占用在模块插件化革新前,咱们只能应用整包工程进行开发,应用整包工程进行日常开发的时候,须要将所有模块下载,而插件化革新实现后,咱们从整包工程拆分出了多个业务插件工程,插件工程的模块数量相比整包工程大幅缩小,插件工程的磁盘占用相比整包工程大幅缩小。下图是整包工程和局部业务插件工程磁盘大小比照: ...

June 8, 2022 · 1 min · jiezi

关于ios:Xcode-绑定按钮

首先,StoryBoard 中定义好的 ViewController 的 class 应该要填和这里的 ViewController.swift 中定义的类同名。这样故事板才会和 .swift 文件分割在一起、反对连线操作。 定义 action 函数,设定 sender 为 UIButton ,能够发现函数右边呈现了小加号。 点住小加号能够拖出一条线,线指向的中央就是要绑定的指标。 松开就能够实现绑定。实现点击按钮就能够执行到相应函数。 这时到 Main.stotyboard  中看按钮到属性,它到 action 中, 多了一个 action。 从 storyBoard 来绑定进入 Main.storyboard 查看按钮的属性,点住它的 action 的小圈。 把它连线到要要触发到函数上。 松开就能够实现绑定。

May 29, 2022 · 1 min · jiezi

关于ios:Xcode-建立-UIKit-项目Hello-World

Xcode 建设 UIKit 我的项目(Hello World)新建 StoryBoard 我的项目新建工程 File>New>Project 抉择 App 而后 next 写下本人的我的项目名,这里我写 Test 界面抉择 StoryBoard StoryBoard 与 controller 的绑定Main.storyboard 的 View Controller 能够填写自定义的 title 将这个 View Controller 绑定到本人定义的 ViewController 类 与这里的 .swift 文件对应 配置解读info.plist 文件寄存一想工程配置,如下图。 Delegate Name 是放代理的名字,这里它默认为:$(PRODUCT_MODULE_NAME).SceneDelegate,与左侧的 SceneDelegate 对应。SceneDelegate 用于解决与 UI 相干的内容。StoryBoard Name 寄存次要故事板名字,它默认为 Main ,与左侧的 Main.storyboard 文件对应。 应用 UIKit 减少一个按钮在 ViewController 的重载函数 viewDidLoad 中增加一个按钮,这种 #selector 的模式要应用 Object-C 的函数调用。 let confirm = UIButton(frame: CGRect(x: 10, y: 40, width: 100, height: 40))confirm.backgroundColor = .greenconfirm.setTitle("He", for: .normal)confirm.setTitleColor(.white, for: .normal)confirm.addTarget(self, action: #selector(ViewController.press), for: .touchUpInside)self.view.addSubview(confirm)在 ViewController 中增加一个 objc 的函数,作为按钮的点击响应事件。 ...

May 29, 2022 · 1 min · jiezi

关于ios:Create-an-Empty-iOS-Project

Choose the other-empty project. Then fill some message. Create three folders and firstly create a new file in the view. Choose the storyboard. I set the name as home. Set the view controller as the initial controller, so the this view controller will be the entry point of the App view.

May 26, 2022 · 1 min · jiezi

关于ios:iOS-lldb寄存器读写Macho解析

咱们明天探讨的是办法调用的传参,寄存器是怎么运作的:首先咱们在一个办法里打上断点,lldb输出re re打印所有寄存器的值惟一的输出参数,是在x2寄存器里,咱们当初看看能用什么办法读出寄存器里的值,memory read 0x0000000100b24850这里能够看到是占32位的一个数据结构,再这里咱们要先回到MachOView里查看这个地址所在的数据是什么样子的,首先咱们通过减去ASLR的值找到MachoView里的地址关上MachOView,数据是这样的,总共32位,咱们以8个字节来宰割来解析这个数据结构,最高8字节是示意数据的大小,次高8字节是示意寄存的是地址指向真正的内容,次次8字节可能存发的是类型???0x07c8,最低8字节可能是寄存的是给指针调配的地址图解:最高8字节在memory read 最高8字节是0A 00 00 00 00 00 00 00咱们先看最高8字节,因左边是高位,它的数据得从右向左读(是一个字节一个字节的读的,16进制两位示意一个字节)00 00 00 00 00 00 00 0A由此得出和MachOView这里的值是合乎的 次高8字节在memory read 次高8字节是7f b0 62 04 01 00 00 00,因左边是高位从右向左读失去0x000000010462b07f减去ASLR失去0x000000010001f07f去MachOView里寻找0x000000010001f07f果然是对应的字符串,这里是寄存在__TEXT,__cstring里,示意是不可批改的.在lldb读出字符串内容,因为咱们得悉字符串大小是10字节,由此咱们能够以memory read -c 10读出字符串,后记:字面量字符串是寄存在__TEXT,__cstring里的,比如说下图中的appsafekb而oc字符串类的属性是放在__DATA,__cfstring里的,比如说上图的_jsonName 示例:在函数里定义一个字符串变量,NSString *key = @"songxuhua_OK";由此可见,字符串变量地址指向的是一个占有32字节的空间,16~23字节所寄存的地址指向字符串的内容,23~31字节寄存的是字符串大小,前16字节临时不是很分明代表啥 memory read具体应用办法x/memory read:dump指定地址的内存(Read from the memory of the process being debugged),后接起止地址或-c指定count加起始地址。可help mem read查看帮忙: Syntax:memory read[] Command Options Usage:size指定内存块(block/item)的大小,默认为1byte。--size):The size in bytes to use when displaying with the selected format. count指定内存块(block/item)的个数,可配合起始地址应用。-c( --count):The number of total items to display. ...

May 17, 2022 · 1 min · jiezi

关于ios:苹果发布-iOS-155-正式版减少卡顿更流畅支持部分应用第三方支付

北京工夫 5 月 17 日凌晨,苹果向用户推送了 iOS 15.5 和 iPadOS 15.5 的正式版本,此次更新次要包含细节改良和 Bug 修复。 次要更新内容Apple Pay Cash 领取钱包 App 当初减少了“申请”和“发送”按钮,不便 Apple Cash 卡用户进行转账和收款。 减少内部领取链接iOS 15.5 容许局部 App 应用第三方领取渠道,如支付宝、微信等。但目前仅针对“浏览类利用”凋谢第三方领取,这类利用泛指提供数字内容的应用程序,如杂志、报纸、书籍、音频、音乐、视频、Spotify、 Netflix 等。 照片回顾性能iOS 15.5 零碎自带的照片利用中可增加“敏感地点”列表,增加后在“回顾”中不会显示这些地点的照片。 基带降级基带版本升级到 1.61.00,大幅改善 iPhone 的信号状态。 通用管制降级在 iPadOS 15.5 中,通用管制已从 Beta 版本升级到正式版,并修复了之前存在的 Bug,能够应用一套键盘/鼠标来管制 iPad、Mac 等设施。 播客更新苹果 Podcasts 播客利用当初容许用户本人设定利用的存储容量下限,达到上线后此利用将不再下载新内容,同时会主动删除旧内容,避免利用占用太多存储空间。 更晦涩更省电苹果官网在 iOS 15.5 的更新文档里并没有提到这一部分,但据开发者走漏,此版本在应用感触上的确较前一个版本更加晦涩。 此外,有外媒对 iOS 15.5 的电池续航进行了测试,后果发现比照 iOS 15.4.1,iOS 15.5 续航工夫减少了 0.12%,并没有大幅晋升。

May 17, 2022 · 1 min · jiezi

关于ios:Swift-Learning-Summary-Nested-Types

Nested TypesEnumerations, classes or structures can be nested in another type. struct Closh { enum Size: String{ case H = "high", M = "Medium", L = "Low" } enum Detail: Int { case H = 180, M = 170, L = 160 struct Price { let normal: Int, discount: Int? } var price: Price { switch self { case .H: return Price(normal: 100, discount: 90) case .M: return Price(normal: 90, discount: 80) case .L: return Price(normal: 80, discount: 70) default: return Price(normal: self.rawValue, discount: nil) } } } let size: Size, detail: Detail var description: String { return "\(size.rawValue), PriceNormal: \(detail.price.normal) PriceDiscount: \(detail.price.discount)" }}var closh = Closh(size: .M, detail: .M)print(closh.description)// Print: Medium, PriceNormal: 90 PriceDiscount: Optional(80)Referring to Nested Types ...

May 16, 2022 · 1 min · jiezi

关于ios:Swift-Learning-Summary-Type-Casting

Type CastingType casting in Swift is implemented with is and as operators. Type casting: A subclass instance can be use as a superclass instance.Defining a Class Hierarchyclass Media { var name: String init(name: String) { self.name = name }}class Song: Media { var artist: String init(name: String, artist: String) { self.artist = artist super.init(name: name) }}class Movie: Media { var director: String init(name: String, director: String) { self.director = director super.init(name: name) }}var library = [ Movie(name: "A", director: "Michael"), Song(name: "B", artist: "Elvis"), Movie(name: "C", director: "Orson"), Song(name: "D", artist: "Rick"), Media(name: "E")]// The "library" is inferred to be [Media] for item in library { print(item.name) // Here the item is of "Media" type }// If we want to use the library's item as the subclass instance, we should downcast the item.Checking TypeUse is to check whether an instance is of a certain subclass type. ...

May 16, 2022 · 3 min · jiezi

关于ios:iOS-macho-中外部函数lazy调用

这里咱们探讨的是iOS是如何懒加载调用内部函数的,比如说:NSLog这里次要波及到__stubs 、__stub_helper、__la_symbol_ptr、__got.__stubs 桩代码,寄存的是懒加载内部函数的十六进制指令,通过https://armconverter.com/?dis... 网页能够转换hex code和arm64汇编代码,这里个别是三行汇编,举例: NOPldr x16,#0x12bc //(这里会依据以后指令地址+0x12bc计算失去地址跳转到__la_symbol_ptr)br x16__la_symbol_ptr 存储的懒加载函数指针,编译时存储的是__stub_helper地址,第一次懒加载实现之后,存储的值会被批改成真正的函数地址 __stub_helper 桩辅助指令,次要是去获取函数地址后,调用_dyld_stub_binder函数绑定到__la_symbol_ptr上 __got 非懒加载函数指针,_dyld_stub_binder就是在此中央,会在程序启动的机会立马绑定. 上面我以一个demo为例在xcode里和MachOView里来探寻一下,懒加载函数调用的过程: NSLog(@"\nClass:%@ \naddress:%p\nContent:%@",object_getClass(str2),str2,str2);NSLog(@"songxuhua");第一个NSLog调用咱们在两个NSLog处打上断点,xcode运行程序,在Debug->Debug Workflow抉择Always show disassembly,能够在运行时展现汇编,下图展现第一个断点处的汇编如上图所示,可知是bl到stub里的NSLog的地址,关上MachOView,查看__stubs发现存储的是一段数据,经由arm汇编和数据互转转换失去汇编如下 nop ldr x16, #0x1c74br x16让咱们看看xcode里,按住ctrl+step into键,进入指令级的调试进到NSLog __stubs的指令,发现和下面MachOView转换的汇编如同差了4个字节,不要焦急,是因为MachOView里的offset是63AC,而xcode里的应该是做过偏移修改的(因为在xcode里的地址是ldr作为以后指令,而MachOView是nop为以后指令),image list -o -f得悉ASLR偏移为d4c000,d523ac-d4c000=63ac,可知的确是跳入了stubs里 (lldb) image list -o -f |grep TestForObjc[ 0] 0x0000000000d4c000 /Users/ijm/Library/Developer/Xcode/DerivedData/TestForObjc-agwmebvcxfuznzcevpmyvcrnwcuj/Build/Products/Debug-iphoneos/TestForObjc.app/TestForObjc好,上面来确定下这段汇编做什么的,首先第一行nop,除了占4个byte位并无其余作用,ldr x16,#0x1c70 大略是相当于从以后指令的地址(63b0)+偏移0x1c70 =0x8020 br x16 跳转执行0x8020,咱们在MachOView找找0x8020是干啥的,发现指到了__la_symbol_ptr__la_symbol_ptr里的数据位64d8,这里就是__stub__helper的中央了比照下xcode里也是一样的,只是加了ASLR偏移,d524d8-d4c000=64d8,刚好咱们来看看_stub_helper干了些啥,首先ldr w16,0x1000064e0读取64e0的指存储在w16寄存器,而后b 0x1000064c0,跳转到了_stub_helper顶部能够看到的是跳转到_dyld_stub_binder函数做绑定,ldr x16,#0x1b40,ldr里地址带#示意绝对以后地址偏移量,0xd524d0-0xd4c000+0x1b40=0x8010,0x8010就到了_got里,改地址寄存着dyld_stub_binder的地址,动态的时候是00000...,在运行时启动的时候,non lazy加载绑定上真正的函数地址 第二次NSLog调用调试到第二个NSLog调用,按住ctrl+step into键,进入指令级的调试持续ctrl+step,发现其最终跳入了Foundation NSLog的地址,阐明在_la_symbol_ptr曾经绑定上了NSLog函数地址,间接br调用了 由此咱们总结如下:第一次调用内部函数,会由stubs-->la_symbol_ptr-->_stub_helper-->dyld_stub_binder绑定后能力调用,当前调用都说stubs-->la_symbol_ptr就能调用到指定函数 知识点总结:1.ldr绝对地址,带#立刻数的示意从以后地址偏移,例如:ldr x16,#0x1b40 ,示意从以后指令地址+0x1b40的地址处读取值付给x16寄存器2.ldr相对地址,带立刻数无#前缀,示意相对地址,例如:ldr w16,0x1000064e0,示意从0x1000064e0地址处读取值复制给w16寄存器3.ctrl+ step into能够进入指令级的调试4.汇编里也能够打断点

May 9, 2022 · 1 min · jiezi

关于ios:Swift-Learning-Summary-Concurrency

ConcurrencySwift has built-in support for writing asynchronous and parallel code in a structured way. Parallel code means multiple pieces of code run simultaneously. Concurrency will make the code harder to debug.Swift can help to catch problem at compile time.Although it’s possible to write concurrent code without using Swift language support, that code tends to be hard to read. listPhotos(inGallery: "Summer Vacation") { photoNames in let sortedNames = photoNames.sorted() let name = sortedNames[0] downloadPhoto(named: name) { photo in show(photo) }}Keywords: ...

May 8, 2022 · 4 min · jiezi

关于ios:一次IOS通知推送问题排查全过程

原创:打码日记(微信公众号ID:codelogs),欢送分享,转载请保留出处。发现问题在上周一个将要上班的夜晚,测试忽然和我打招呼,说IOS推送的修复更新上线后存在问题,后盾报错。 连忙跑到测试那里看报错详情,报错如下: 重现问题看到这个报错后,在网上搜寻了一下,这种谬误个别都是因为客户端不信赖服务端SSL证书导致的,回忆工作以来,如同遇到这种问题好屡次了,只有将证书导入一下就好了。 因为不能冒然在线上批改解决问题,于是获取推送相干信息(如:设施token)后,到本人电脑下来测试,看是否能重现问题。 啪啦啪啦,代码批改结束,点运行坐等谬误呈现。 5秒钟过后,发现推送音讯发送胜利了,没有呈现报错,有点懵逼!心里想,代码都是齐全一样的啊,怎么线上报错,我这却是好的呢??? 纠结了一会,于是开始静下心来剖析: 代码必定是一样的,应该不是外表上的代码起因。其次推送设施也是一样的,应该也不是手机问题。那么。。。就在没有脉络之际,我又扫了一眼工程目录,发现了jdk8,但咱们线上零碎应用的是jdk7啊。 于是我将本人工程的jdk8换成jdk7试一下,同样的报错终于呈现了! 那为什么jdk8没问题,jdk7却报错呢??? 寻找起因围绕着网上的说法和之前的教训,这hand_failure谬误应该是SSL/TLS握手过程中不信赖服务端证书导致的,那方法很简略,去苹果官网找到苹果服务端提供的证书,导入到java的证书信赖库cacert文件中即可。 于是,下载了证书文件GeoTrust_Global__CA.cer,并用jdk自带的keytool工具将证书导入到cacert文件中,如下: 如上,导入过程中,发现提醒曾经有这个证书了,过后没想那么多,再导一次试试吧! 导入后,再次运行代码,后果还是报错! 心里又慌乱起来,没招了,于是又百度/google去了,但搜寻进去的论断简直都是证书信赖问题,和本人的招式一样! 同时,也理解了一下SSL/TLS协定相干常识,大抵握手过程如下: 具体如下: 客户端发送clientHello音讯,通知服务端我应用的TLS版本与加密套件等。服务器返回serverHello音讯,通知本人抉择哪个TLS协定版本与加密套件等。服务器发送Certification音讯,将本人的数字证书(包含服务器名称、CA和公钥)作为音讯内容发给客户端。客户端Certificate verify校验服务器的数字证书的有效性。客户端Change cipher spec抉择加密套件并生成会话密钥(客户端与服务器之间后续的数据传输将应用此会话密钥)。客户端、服务器之间发送加密数据。另外,jvm有一个-Djavax.net.debug=SSL的参数,能够把SSL/TLS的握手过程都在控制台通过日志显示进去,如下: Ok,既然晓得了握手过程,那就把SSL/TLS的日志显示进去看一下吧,看看是什么阶段呈现的问题,如下: 这阐明GeoTrust_Global.cer证书的确曾经增加到信赖库中了,而具体的SSL日志如下: 如上图,报错产生在clientHello发送之后,在读服务端返回的serverHello音讯时,却读到的是Alert:handshake_failure正告信息,而后SSL握手就中断了,就如同你在和服务器打招呼,而后服务器回复了一个滚蛋一样! 百思不得其解? 筹备放弃一会,我看到测试走了过去。 测试:“问题解决得怎么样了,啥状况啊” 我:“还不晓得,原本认为很简略,实际上并没有,jdk8能够,7不行” 测试:“好吧” 我:”要不降级jdk8吧“ 测试:”能行吗“ 我:”......能行,jdk兼容性都很好,而且其它零碎都曾经降级过了,这个零碎原本也打算要升,问题不大“ 测试:”......好的“ 于是,测试去降级jdk8了,原本我应该站在测试身后期待问题被解决,但我还是想在这期间查一查根本原因,于是又推敲了起来。 发现假相回想起,这个零碎以前原本是jdk6,就是因为苹果强制开发者必须应用Https,且须要TLSv1.2版本,而jdk7才开始反对TLSv1.2,所以这个零碎才降级到jdk7,那当初这个报错会不会... 于是,我连忙应用TLSv1.2试试,增加jvm参数-Dhttps.protocols=TLSv1.2即可强制https应用TLSv1.2版本协定,如下: 加完后再次运行,报错仍旧,那还有哪里可能会有问题呢? 我忽然灵光一闪,应用jdk7运行一次,再应用jdk8运行一次,将两次的SSL日志比照一下,看看哪里不一样,说不定能找到线索! 于是我马上试运行并比照两次SSL日志,发现两次SSL日志中TLS协定应用的加密套件不同,如下图: jdk7的调试信息如下 : jdk8的调试信息如下: jdk8的TLS握手在服务端ServerHello之后,抉择的加密套件是TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,而jdk7中可供选择的加密套件中没有TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384。 问题差不多清晰了,应该是jdk7中的加密套件,苹果服务器感觉太老不平安,都不反对了,那么如果我应用jdk8,并将加密套件强制为jdk7中的加密套件呢,应该也是会报错的! 于是,我还是应用jdk8,并增加了jvm参数-Dhttps.cipherSuites=SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA,SSL_RSA_WITH_RC4_128_MD5,SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA,以强制jdk8应用jdk7的加密套件,如下: 再次运行后,果然报错了!所以应该是jdk8反对了一些新的加密套件,而苹果服务端只认这些新的加密套件导致的。 于是,我去jdk官网,查了一下jdk8的新增个性,发现TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384中AES加密算法的GCM模式在jdk8中才反对,如下: 至此,问题起因全副搞清楚了,测试降级jdk8后也报告推送失常,此时已是10点多,两人写写日报连忙回家去了...... 往期内容密码学入门 时区的坑,不想再踩了! 常见的Socket网络异样场景剖析 字符编码解惑

May 4, 2022 · 1 min · jiezi

关于ios:Swift-Learning-Summary-Optional-Chaining

Optional ChainingA process for querying and calling properties, methods, and subscripts on an optional that might currently be nil .Multiple queries can be chained together, and the chain fails gracefully if any link in the chain is nil . Optional Chaining as an Alternative to Forced Unwrapping! force unwrapping triggers a runtime error when the optional is nil .Use the optional chaining to check if the optional value querying is succeed. ...

May 2, 2022 · 3 min · jiezi

关于ios:Swift-Learning-Summary-Deinitialization

DeinitializationA deinitializer is called immediately before a class instance is deallocated. Write with deinit keyword. Swift manage the instance memory through automatic reference counting. Deinitializer can access all properties of the instance, and do some work to release the handlers (such as close a file). Class definition can have at most one deinitializer per class. It doesn’t take any parameters. // The function creat a cat and the cat will destory after the function end.class Cat { init () { print("Create") } deinit { print("Destory") }}func run() { var cat = Cat()}run()// Print:// Create// DestoryDeinitializers in ActionHere shows a static Bank that own some coins. When create a new player, the player get coins from the Bank. And the player give back the coins to the Bank before the player is deinitialized. ...

May 2, 2022 · 2 min · jiezi

关于ios:Swift-Learning-Summary-Initialization

InitializationInitialization is the process of preparing an instance of a class, structure or enumeration for use. Properties were set as an initial value. Initializers are the implements of the process of initialization. The initializers can be override. Unlike Object-C, Swift initialization has no return value. Initialization for an InstanceClasses and structures must set all of their stored properties to an appropriate initial value when using the initializer. (When assign a default value to a stored property or set its value within an initializer, the property is set directly without calling any property observers) ...

April 30, 2022 · 14 min · jiezi

关于ios:Swift-Learning-Summary-Inheritance

InheritanceClass A inherit from class B. Then A is the so call subclass, B is the superclass. Subclass can do: Access methods, properties, and subscripts belonging to their superclass,Override the methods, properties and subscripts.Extends the functionality of the superclass.Superclass can do: Add property observer to inherited properties. (In order to be notified when the value of property changes)Usageclass Card { var number: Int? func changeNumber(number: Int) -> Bool { self.number = number return true }}// Inherit from Cardclass StudentCard: Card { var studentID: Int?}// Inherit from Cardclass BankCard: Card { var account = 0}var studentCard = StudentCard()studentCard.number = 123studentCard.studentID = 220022print(studentCard.number!)print(studentCard.studentID!)var bankCard = BankCard()bankCard.changeNumber(number: 124)bankCard.account = 100print(bankCard.number!)print(bankCard.account)OverridingA subclass can provide its own custom implementation of an instance method, type method, instance property, type property, or subscript that it would otherwise inherit from a superclass. ...

April 24, 2022 · 5 min · jiezi

关于ios:Swift-Learning-Summary-Subscripts

SubscriptsA shortcut for accessing the member of a collection, list, or sequence.Classes, structures, and enumerations can define subscripts.Get result by square brackets [] .Use the subscript keyword.We can define multiple subscripts for a single type, and the appropriate subscript overload to use is selected based on the type of index value you pass to the subscript. Syntaxsubscript(index: Int) -> Int { get {} set(newValue) {}}subscript(index: Index) -> Int { // return directly}Examplestruct TimesTable { let mul: Int subscript(index: Int) -> Int { return mul * index }}let times = TimesTable(mul: 3)print(times[6])Usageclass Order { var names: [String] = [] subscript(index: Int) -> String { assert(index < names.count, "out of index") return names[index] }}var order = Order()order.names.append("Mike")order.names.append("Amy")order.names.append("John")print(order[1]) // AmyThe Dictionary has implements the subscript. Not all key has value, so the value is optional. ...

April 24, 2022 · 2 min · jiezi

关于ios:ios账号换服失败之记录未完

PART I: 失败的尝试为了能在手机端玩耍亚服原神,申请了一张JCB信用卡。填写材料还算顺利,但最初缺失败了,商店是日语了,但无奈购买。 提醒说转区后订阅会生效,而敌人预先才说转区的时候不能有失效的订阅。起初我查了下,账号里还在失效的订阅服务只有一个,22号到期。 连忙勾销,6天后再试一次 PART II: 未完待续

April 17, 2022 · 1 min · jiezi

关于ios:Swift-Learning-Summary-Method

MethodMethods are functions that associated with a particular type. Classes, structures and enumerations. Define instance methods for an instance of the given type.Define type method for the type itself.Instance MethodIt is defined in a type. And it can only be called by a specific instance of the type. class Bird { var energy = 10 // Instance method func sing() { energy -= 1 } // Instance method func eatFood(food: Int) { self.energy += food // self is current instance of the type, it's the instance who call the current method. } func setEnergy(energy: Int) { self.energy = energy // Here must use the 'self' to distinguish the property of the instance and the method's parameter. }}var keo = Bird()keo.eatFood(food: 4)print(keo.energy) // 14keo.sing()print(keo.energy) // 13Modifying Value Types in the Instance MethodStructures and Enumerations are value type, their properties can’t be modified by default. ...

April 17, 2022 · 3 min · jiezi

关于ios:Swift-Learning-Summary-Properties

PropertiesStored properties Only provided by classed and structures. Computed properties Provide by classes, structures, enumerations. Usually associated with instance of a particular type, can be associated with the type itself(type properties). Can define property observers to monitor changes in a property’s value, which can respond to with custom action. Can use a property wrapper to reuse code in the getter and setter. Stored Properties**struct Setting { var width: Int let height: Int }var appSetting = Setting(width: 100, height: 200)appSetting.width = 150let constSetting = Setting(width: 110, height: 210)//constSetting.width = 120 // This will trigger a compile-time error, the struct is of const value type.**Lazy Stored PropertiesIts initial value isn’t calculated until the first time it’s used. ...

April 17, 2022 · 9 min · jiezi

关于ios:iOS开发基础C语言数据类型和运算符

第2章 数据类型和运算符2.1 正文程序正文是源代码的一个重要局部,对于一份标准的程序源代码而言,正文应该占到源代码的1/3以上;单行正文 //;多行正文 /*正文开始和*/正文完结,须要指出的是多行正文不能够嵌套,在/**/多行正文代码块内,不能再次应用/**/增加多行正文;2.2 标识符和变量2.2.1 分隔符Objective-C语言里的分号(;)、花括号({})、方括号([])、圆括号(())、空格、圆点(.)都具备非凡的分隔作用,因而被统称为分隔符。 分号 Objective-C语言里语句的分隔不是应用回车来实现的,而是采纳分号(;)作为语句的分隔,因而,每个Objective-C 语句必须应用分号作为结尾。Objective-C 程序容许一行书写多行语句,每个语句之间以分号隔开即可,单从程序的可读性角度来看,应该防止在一行书写多个语句;一个语句也能够跨多行,只有在最初完结的中央应用分号完结即可。花括号 花括号的作用就是定义一个代码块,一个代码块指的就是" {" 和" }" 所蕴含的一段代码,代码块在逻辑上是一个整体。方括号圆括号空格 Objective-C 语言中的空格蕴含空格符(Space)、制表符(Tab) 和回车(Enter) 等。除此之外,Objective-C 源程序还会应用空格来正当缩进代码,从而提供更好的可读性。圆点2.2.2 标识符规定标识符,就是用于给程序中变量、类、办法命名的符号。规定如下: 标识符能够由字母、数字、下画线(_)和美元符($)组成,其中不能以数字结尾;标识符不能是Objective-C 关键字,但能够蕴含关键字;标识符不能蕴含空格;标识符只能蕴含美元符($),不能蕴含@、#等其余特殊字符;Objective-C语言是辨别大小写的。因而,abc 和Abe 是两个不同的标识符;2.2.3 Objective-C 关键字autobreakcasecharconstcontinuedefaultdodoubleelseenumexternfloatforgotoifintlongregisterreturnshortsignedsizeofstaticstructswitchtypedefunionunsignedvoidvolatilewhile2.3 数据类型分类Objective-C语言其实就是C语言的超集,因而,它支待的数据类型与C 根本类似,大抵分类如下:数据类型: 根本类型 整型字符型浮点型 float类型double类型枚举型构造类型 数组类型构造体类型共用体类型指针类型 指针类型既是C 语言最重要的数据类型,也是Objective-C 最重要的类型,所有的零碎类、自定义类的实质都是指针类型。还有一种非凡的空类型(null type), 空类型就是nil 值的类型,这种类型没有名称。因为空类型没有名称,所以不可能申明一个空类型的变量,或将变量转换成空类型。空援用(nil) 是空类型变量惟一的值。空援用nil能够转换为任何援用类型。2.4 根本数据类型2.4.1 整型short int(简称short):在内存中通常占16位,取值范畴:-2^15 ~ 2^15 - 1;int:在内存中通常占32位,取值范畴:-2^31 ~ 2^31 - 1;long int(简称long):在内存中通常占64位,取值范畴:-2^63 ~ 2^63 - 1;long long:在内存中通常占64位,取值范畴:-2^63 ~ 2^63 - 1;须要指出的是,Objective-C 并没有硬性规定各种整型在内存中所占的空间。通常来说,Objective-C 要求long long 型所占用的内存空不小于long 型所占用的内存空间,long 型所占的内存空间应该不小千int 所占的内存空间,int 型所占的内存空间应该不小于short 型所占用的内存空间。 ...

April 10, 2022 · 4 min · jiezi

关于ios:Swift-Learning-Summary-Structures-and-Classes

Structures and ClassesStructures and classes are the basic building blocks of the program’s code. They have properties and functions. We can define a structure or class in a single file, the external interface of that structure or class is automatically made for other code to use. The common things:Define properties to store valuesDefine methods to provide functionalityDefine subscripts to provide access to their values using subscript syntaxDefine initializers to set up their initial stateBe extended to expand their functionality beyond a default implementationConform to protocols to provide standard functionality of a certain kindThe additional capabilities that classes support:Inheritance enables one class to inherit the characteristics of another.Type casting enables you to check and interpret the type of a class instance at runtime.Deinitializers enable an instance of a class to free up any resources it has assigned.Reference counting allows more than one reference to a class instance.UsagesDefinitionstruct Cat { var weight = 3 var legCount = 4}class Dog { var weight = 5 var legCount = 4 var cloth = Cloth() // Every dog has a cloth in red color. var name = String?}class Cloth { var color = "red" var width = 15 var length = 45}Create Instancelet cat = Cat()let dogA = Dog()let dogB = Dog()let cloth = Cloth()Access Propertiesprint(cat.legCount)print(dogA.legCount)print(dogB.cloth.color)Initializeclass Dog { var weight: Int var legCount: Int init (){ self.weight = 5 self.legCount = 4 } init (weight: Int, legCount: Int = 4){ self.weight = weight self.legCount = legCount }}let dog = Dog(weight: 8)print(dog.weight) // 8print(dog.legCount) // 4Structures and Enumerations Are Value TypesValue type will be copied the whole value when it’s being assigned. ...

April 10, 2022 · 4 min · jiezi

关于ios:Swift-Learning-Summary-Enumeration

EnumerationsSyntaxenum Direction { case up case down case left case right}Multiple case can appear on a single line, separated by commas: enum { case up, down, left, right}Use the Enumeration var dir = Direction.upWhen we want to modify the var after the initialized, we can use a shorter form of the enumeration. var dir = Direction.updir = .down // The value's type has been inferred when the value is in initializing.Matching Enumeration Values with a Switch Statementenum Direction { case up case down case left case right}var dir = Direction.rightswitch dir {case .up: print("Go up")case .down: print("Go down")case .left: print("Go left")case .right: print("Go right")}Iterating over Enumeration CasesConform to the CaseIterable protocol, to make the enumeration’s case be iterable. ...

April 10, 2022 · 3 min · jiezi

关于ios:Swift-Learning-Summary-Closures

ClosuresClosures are self-contained blocks of functionality that can be passed around and used in your code. Global and nested functions are special cases of closures. Global functions are closures that have name and don’t capture any value.Nested functions are closures that have a name and can capture values from the enclosing function.Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context.The sort() will sort at original array, and sorted() will sort and return a new sorted array. ...

April 2, 2022 · 8 min · jiezi

关于ios:Swift-Learning-Summary-Function

FunctionThe function has two way to affect the outside scope Use return value to tell the caller.Use the inout with reference to change the the original value outside.Function UsagesWithout Parameter and Return Value func sayHello() { print("Hello")}// Call the function, will print「hello」sayHello() With Parameter func greet(name: String) { print("Hello \(name)") }// Call the function pass the String as the input to the function, will print 「Hello Mike」greet(name: "Mike") With Multiple Parameter ...

April 2, 2022 · 5 min · jiezi

关于ios:几个-iOS-端底层网络问题

典型案例1. Socket 断开后会收到 SIGPIPE 类型的信号,如果不解决会 crash共事问了我一个问题,说收到一个 crash 信息,去 mpaas 平台看到如下的 crash 信息 看了代码,显示在某某文件的313行代码,代码如下 Socket 属于网络最底层的实现,个别咱们开发不须要用到,然而用到了就须要小心翼翼,比方 Hook 网络层、长链接等。查看官网文档会说看到一些阐明。 当应用 socket 进行网络连接时,如果连贯中断,在默认状况下, 过程会收到一个 SIGPIPE 信号。如果你没有解决这个信号,app 会 crash。 Mach 曾经通过异样机制提供了底层的陷进解决,而 BSD 则在异样机制之上构建了信号处理机制。硬件产生的信号被 Mach 层捕获,而后转换为对应的 UNIX 信号,为了保护一个对立的机制,操作系统和用户产生的信号首先被转换为 Mach 异样,而后再转换为信号。 Mach 异样都在 host 层被 ux_exception 转换为相应的 unix 信号,并通过 threadsignal 将信号投递到出错的线程。 有2种解决办法: Ignore the signal globally with the following line of code.(在全局范畴内疏忽这个信号 。毛病是所有的 SIGPIPE 信号都将被疏忽) signal(SIGPIPE, SIG_IGN);Tell the socket not to send the signal in the first place with the following lines of code (substituting the variable containing your socket in place of sock)(通知 socket 不要发送信号:SO_NOSIGPIPE) ...

March 29, 2022 · 3 min · jiezi

关于ios:Swift-Learning-Summary-Control-Flow

Control Flowloop whilefor-inrepeat whilecondition branch ifswitch where guardcontrol transfer statements breakcontinuefallthroughreturnthrowLoopFor-In Loopsvar pets = ["cat", "dog"]for pet in pets { print(pet)}for index in 0..<2 { print(pets[index])}// if we don't need the value from the 0..<2, use the underscore to ignore the value.var n = 1for _ in 0..<2 { print(n) n += 1}var words = [11: "fine", 2: "happiness"]for (key, word) in words { print("\(key): \(word)")}Stride Function let minutes = 60let interval = 5for tickMark in stride(from: 0, to: minutes, by: interval) { // render the mark every 5 minutes. // 0, 5, 10, ... , 50, 55}// closed rangefor tickMark in stride(from: 0, through: minutes, by: inerval { // render the mark every 5 minutes. // 0, 5, 10, ... , 50, 55, 60}The for-in can be only use to the object which conform to the Sequence protocol. ...

March 28, 2022 · 5 min · jiezi

关于ios:Swift-Learning-Summary

Collection Typearraysetdictionarycollection type use are generic, the type of element is specific. ArrayWith ordering.Access by subscript.Variable-length.var someInts: [Int] = []someInts.append(2)someInts = [] // Empty the arrayCreate by class var someDoubles = Array(repeating: 0.0, count: 3)print(someDoubles)var otherDoubles = Array(repeating: 2.5, count: 3)print(otherDoubles)var addedDoubles = someDoubles + otherDoubles // concatenate two array into oneprint(addedDoubles)result: [0.0, 0.0, 0.0] [2.5, 2.5, 2.5] [0.0, 0.0, 0.0, 2.5, 2.5, 2.5] Create By Array Literal ...

March 28, 2022 · 6 min · jiezi

关于ios:基于newpassmanager编写pass

https://blog.csdn.net/dashuni...

March 26, 2022 · 1 min · jiezi

关于ios:FIT3178-iOS-App-Development

FIT3178: iOS App DevelopmentAssignment 4 – Final Mobile App Assignment 4: Final Mobile AppDue Date: Friday Week 14 (10th June, 11:55PM) - Weight: 30% Purpose: The purpose of this assignment is to produce a complete iOS application based on the ideadescribed in your App Design Specification (Assignment 1). This assessment tests your abilityto apply knowledge from all topics covered throughout semester Completion of this assessment should demonstrate the following learning outcomes: ...

March 25, 2022 · 5 min · jiezi

关于ios:iOS-iPadOS-154-正式发布戴口罩解锁-Face-ID仅支持-12-及以上机型

北京工夫 3 月 15 日凌晨,为用户推送了 iOS / iPadOS 15.4 正式版更新,这是 iOS 15 和 iPadOS 15 的第四次重大更新,间隔上一次更新隔了一个月,其中最大的更新就是反对戴口罩应用面容ID。 据理解,该性能的工作原理与一般的Face ID相似,但会扫描眼睛四周的区域以进行身份验证。 值得一提的是,此性能只反对 iPhone 12 及后续机型,iPhone 11 系列及以下机型和反对面容 ID 的 iPad 都没有这一性能。 iPhone 12 及后续机型用户只须要关上零碎内“戴口罩应用 Face ID”的开关之后,从新录入一遍面部数据即可。这项性能实用于解锁手机和领取,比之前应用 Apple Watch 解锁 iPhone 的用处更多。 与此同时,苹果也正告称,因为这种面部身份验证只扫描眼睛四周的面部特色,这种办法的准确性将会升高。 此外,iPadOS 15.4 也带来通用管制性能,用户能够应用雷同的鼠标 / 触控板和键盘管制 Mac 和 iPad。 本次更新还减少了37个新的表情符号,包含人脸、手势和家用物品。 另外,iOS / iPadOS 15.4还反对点击领取,其余更新包含苹果AirTag追踪器的新反跟踪性能,以及间接在设施上将自定义域增加到 iCloud 邮件的选项等等。  最初,这次更新还包含一些 Bug 的修复: 键盘可能在输出的数字之间插入句号明天视图中的新闻小部件在被点击时可能无奈关上文章照片和视频可能无奈同步到iCloud照片库谈话屏幕辅助性能可能会在图书利用中意外退出在控制中心敞开实时收听性能时,可能不会敞开

March 15, 2022 · 1 min · jiezi

关于ios:⑩安全篇史上最全iOS八股文面试题2022年金三银四我为你准备了iOS1000条笔试题以及面试题包含答案

iOS面试题 一共分为口试题和面试题两局部口试题 一共分为10个 总共613题面试题 一共400题 口试题 一个10个系列 别离为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ③(界面篇) 共83题 已更新 ④(iOS篇) 共52题 已更新 ⑤(操作篇) 共68题 已更新 ⑥(数据结构篇) 共23题 已更新 ⑦(多线程篇) 共60题 已更新 ⑧(网络篇) 共22题 已更新 ⑨(多媒体篇) 共59题 已更新 ⑩(平安篇) 共27题 已更新 面试题 一共分为3个 总共400题 ⑪(面试篇 1/3) 共127题 已更新 ⑪(面试篇 2/3) 共137题 已更新 ⑪(面试篇 3/3) 共136题 已更新 @TOC 口试题 613题⭐️⑩、口试题-平安篇(27题)1.3DES和SHA1属于非对称加密的技术?:[判断题][ ] A、正确[x] B、谬误2.MD5属于非对称加密的技术吗?:[判断题][x] A、正确[ ] B、谬误3.以下哪种操作能够无效地爱护 应用程序中的数据?:[多选题][x] A、对设施中存储的内容进行加密。[x] B、对网络传输的数据进行加密。[x] C、应用post申请传递网络数据。[x] D、对账号密码进行加盐操作。4.以下对于DES加密,形容正确的是?:[多选题][x] A、提供高质量的数据保护,避免数据未经受权的泄露和未被觉察的批改[x] B、具备较高的复杂性,使得破译的开销超过可能取得的利益。同时又要便于了解和把握。[x] C、明码体制的安全性应该不依赖于算法的窃密,其安全性仅加密密钥的窃密为根底。[x] D、实现经济,运行无效,并且实用于多种齐全不同的利用。5.3DES是三重数据加密算法的同称,它相当于每个数据利用三次DES加密算法?:[判断题][x] A、正确[ ] B、谬误6.3DES通过减少DES的密钥长度来防止相似地工具,而不是设计一种全新的块明码算法。:[判断题][x] A、正确[ ] B、谬误7.CommonCryptor.h提供了以下哪些加密算法`?:[多选题][x] A、KCCAlgorithmAES128[x] B、KCCAlgorithmDES[x] C、KCCAlgorithm3DES[x] D、KCCAlgorithmBlowfish8.不能够从音讯摘要中还原信息,并且两个不同的音讯不会产生同样的音讯摘要,这样形容SHA1加密算法正确吗?:[判断题][x] A、正确[ ] B、谬误9.对于长度小于 2^64位的音讯,SHA1会产生一个多少位的音讯摘要?:[判断题][ ] A、32[ ] B、64[ ] B、128[x] B、16010.MD5能够将任意长度的字符串编程一个多少bit的大整数:[判断题][ ] A、32[ ] B、64[x] B、128[ ] B、25611.MD5加密算法是可逆的?:[判断题][ ] A、正确[x] B、谬误12.苹果的iOS零碎采纳了以下哪些严格的平安机制?:[多选题][x] A、代码签名[x] B、权限隔离[x] C、可信启动链[x] D、沙盒执行环境13.UseDefaults存储的数据,位于沙盒中的哪个目录?:[单选题][ ] A、Caches/[ ] B、Documents/[x] C、Library/Preferences[ ] D、Temp/14.以下对于归档形容正确的是:[多选题][x] A、归档是一个过程,即用某种格局来保留一个或多个对象,以便当前还原这些对象。[x] B、能够应用归档的办法进行对象的深复制。[x] C、采纳归档的模式来保留数据,该数据对象须要恪守NSCoding协定,并且必须提供encodeWithCoder:和initWithCoder:办法。[x] D、归档的毛病是如果想改变归档数据地某一小部分,则须要解压整个数据和归档整个数据。15.当iPhone重启时,会抛弃哪个沙盒目录下的文件:[单选题][ ] A、Documents[ ] B、Library[ ] C、Preferences[x] D、tmp16.沙盒的哪个目录下的所有文件,都能够通过iTunes进行备份和复原:[单选题][x] A、Documents[ ] B、Library[ ] C、Caches[ ] D、tmp17.沙盒下的哪个目录用来寄存缓存文件,保留从网络下载的申请数据,例如网络下载的离线数据,图片视频文件等?:[单选题][ ] A、Documents[ ] B、Library/Preferences[x] C、Library/Caches[ ] D、tmp18.Library目录下除了Caches自目录外,其它子目录及其文件都能够通过iTunes进行备份?:[单选题][x] A、正确[ ] B、谬误19.沙盒中的tmp目录的内容不会通过iTunes备份,程序员也不须要管 tmp文件夹的开释?[判断题][x] A、正确[ ] B、谬误20.应用程序bundle中次要以下那几个类型的文件?:[多选题][x] A、temp临时文件:用来存储程序运行期间的缓存文件。[x] B、可执行文件:每个利用必须要有一个可执行文件。[x] C、资源文件年:是可执行文件以外的数据文件,罕用的如图片、图标、音频文件、视频文件、配置文件等。[x] D、info.plist:用来配置利用的根本参数信息。包含版本号,指向的可执行文件,包名等。21.应用程序bundle的配置信息,包含了应用程序惟一标识名,版本号,可执行文件名等信息。这些信息都存储在哪个文件中?:[单选题][ ] A、config.plist[ ] B、property.plist[x] C、info.plist[ ] D、userinfo.plist22.在info.plist中,以下那个键用来存储应用程序的惟一标识?:[单选题][ ] A、CFBundDisplayName[ ] B、CFBundExecutable[ ] C、CFBundldVersion[x] D、CFBundIdentifier23.keychain是独立于每个App的沙盒之外的,所以即便App被删掉后。keychain外面的信息仍然存在?:[判断题][ ] A、不是[x] B、是24.在沙盒环境测试App Store内购流程的时候,能够应用越狱的设施吗?:[判断题][ ] A、能够[x] B、不能够25.在沙盒环境测试App Store内购流程的时候,我的项目Bundle identifier如果和申请AppID时填写的bundleID不统一,能够申请到内够我的项目吗?:[判断题][ ] A、能够[x] B、不能够26.在沙盒环境测试App Store内购流程的时候,必须应用测试账号,而无奈应用实在的Apple账号?:[判断题][ ] A、正确[x] B、谬误27.以下对于苹果对沙盒的限度,形容正确的是?:[多选题][x] A、应用程序在本人的沙盒中运作,但不能拜访工作其余应用程序的沙盒。[x] B、利用之间不能共享数据。沙盒里的文件不能被复制其余沙盒。[x] C、应用程序的文件夹中,也不能把其余利用文件夹复制到沙盒。[x] D、苹果禁止任何读写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中。

March 15, 2022 · 1 min · jiezi

关于ios:⑨多媒体篇史上最全iOS八股文面试题2022年金三银四我为你准备了iOS1000条笔试题以及面试题包含答案

iOS面试题 一共分为口试题和面试题两局部口试题 一共分为10个 总共613题面试题 一共400题 口试题 一个10个系列 别离为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ③(界面篇) 共83题 已更新 ④(iOS篇) 共52题 已更新 ⑤(操作篇) 共68题 已更新 ⑥(数据结构篇) 共23题 已更新 ⑦(多线程篇) 共60题 已更新 ⑧(网络篇) 共22题 已更新 ⑨(多媒体篇) 共59题 已更新 ⑩(平安篇) 共27题 已更新 面试题 一共分为3个 总共400题 ⑪(面试篇 1/3) 共127题 已更新 ⑪(面试篇 2/3) 共137题 已更新 ⑪(面试篇 3/3) 共136题 已更新 @TOC 口试题 613题⭐️⑨、口试题-多媒体篇(59题)1.以下那些事Cocoa Touch框架,用于解决音频和视频:[多选题][x] A、Core Audio[x] B、OpenAL[x] C、Media Library[x] D、AV Foundation2.以下那些是Cocoa Touch框架,用于解决图形和动画:[多选题][x] A、Metal[x] B、Core Animation[x] C、OpenGL ES[x] D、Quartz 2D3.在线播放视频个别拜访服务器的哪种类型文件:[单选题][x] A、M3U8[ ] B、flv[ ] C、MP4[ ] D、data4.iOS中的动画实现技术次要是哪两个框架:[多选题][x] A、Core Animation[ ] B、Core Graphic[ ] C、Foundation[x] D、UIKit5.以下UIView的哪些属性能够产生平滑的动画:[多选题][x] A、frame[x] B、bounds[x] C、center[x] D、backgroundColor6.以下UIView 动画曲线类型,哪种示意动画速度由慢变快?[多选题][ ] A、easeInOut[x] B、easeIn[ ] C、easeOut[ ] D、linear7.应用UIImageView的animationImages属性播放动画,图片序列中的图片须要具备雷同的尺寸,如果序列的图片具备不同的尺寸,可能会产生意料之外的动画成果?[多选题][x] A、正确[ ] B、谬误8.在iOS开发中,能够应用哪些音频播放技术计划?[多选题][x] A、System Sound Services[x] B、AVAudioPlayer[x] C、Audio Queue Services[x] D、Open AL9.应用 System Sound Services 播放音频,有哪些特点?[多选题][x] A、播放的声音长度要小于30秒[x] B、声音文件的格局必须是 PCM 或 IMA4(IMA/ADPCM)[x] C、能够管制音频播放的进度[x] D、调用办法后 立刻播放声音,并且无奈设置声音大小10.应用 System Sound Services 播放音频,无奈间接进行循环播放 立体声播放的管制 ?[判断题][x] A、正确[ ] B、谬误11.应用 AVAudioPlayer技术,能够实现以下哪些性能?[多选题][x] A、播放任意时长的音频文件[x] B、播放文件中或者内存缓存区中的声音[x] C、进行音频文件的循环播放[x] D、应用多个AVAudioPlayer实例,能够同时播放多个音频文件12.应用 AVAudioPlayer技术,能够管制播放的音量,设置立体声,还能够设置播放中的声音速率?[判断题][x] A、正确[ ] B、谬误13.应用 AVAudioPlayer技术不反对进行声音播放的快进和后退?[判断题][ ] A、正确[x] B、谬误14.在iOS开发中播放视频,通常采纳哪两种形式?[多选题][ ] A、OpenGL ES[ ] B、Core Graphics[x] C、MPMovePlayerController[x] D、AVPlayer15.Quartz 2D在iOS开发中,能够实现以下哪些工作?[多选题][x] A、绘制一些零碎UIKit框架中不好展现的内容,例如饼图[x] B、绘制图形:线条、三角形、矩形、圆、弧等[x] C、读取和生成PDF[x] D、截图和裁剪图片16.Quartz 2D 不具有以下哪些性能?[单选题][ ] A、path-based drawing[ ] B、offscreen rendering[x] C、Animation[ ] D、anti-aliased rendering17.在Quartz 2D中,应用含有Create或者Copy的函数创立的对象,应用完后必须开释,否则将导致内存泄露?[判断题][x] A、正确[ ] B、谬误18.和UIKit的坐标系一样,Quartz 2D的坐标系原点也是在屏幕的左上角?[判断题][ ] A、正确[x] B、谬误19.在Quartz 2D中,应用办法 CGContextAddLineToPoint挪动画笔到一个点来开始新的子门路?[判断题][ ] A、正确[x] B、谬误20.对于AVPlayerLayer实例的videoGravity属性,以下哪一项能够保留视频的宽高比,并对视频进行缩放,以填满层的范畴区域?[单选题][x] A、AVLayerVideoGravityResizeAspectFill[ ] B、AVLayerVideoGravityResizeAspect[ ] C、AVLayerVideoGravityResize[ ] D、都不是21.以下哪个框架能够让开发者自在、不便地调整 全副 或局部文字的色彩、尺寸、地位布局等属性,能够更加便捷地创立杂志、日记类的利用?[单选题][ ] A、UIKit[ ] B、Foundation[x] C、Core Text[ ] D、Core Image22.以下哪个是Core Text的字形绘制 最小的单位?[单选题][ ] A、CTFrame[x] B、CTRun[ ] C、CTLine[ ] D、CTPath23.以下对于TextKit,说法正确的是?[多选题][x] A、为了给开发者提供更高效的文字排版工具,在iOS7.0中Apple向开发者推出了Text Kit类库[x] B、Text Kit类库是建设在Core Text根底之上的。[x] C、Text Kit和 UILabel、UITextView等控件紧密结合,在应用这些控件时,能够间接应用TextKit相干的性能。[x] D、Text Kit 和 Web Kit 一样,都是建设在Core Graphics和Core Text 框架之上。24.应用Core Image 能够实现上面哪些工作?[多选题][x] A、应用内置的滤镜对图片进行疾速的艺术解决和加工。[x] B、对人脸等特色进行检测。[x] C、同时应用多个滤镜以产生更加复杂多变的自定义成果。[x] D、创立运行在GPU上的自定义滤镜进步图像处理的速度。25.Core Image图像处理框架是从哪个iOS版本退出进来的?[单选题][x] A、iOS 5.0[ ] B、iOS 6.0[ ] C、iOS 7.0[ ] D、iOS 8.026.图像处理框架是基于什么对图像进行剖析与解决的?[单选题][ ] A、色彩[x] B、像素[ ] C、点[ ] D、直方图27.Core Image在iOS6之后的滤镜 数量减少至多少个?[单选题][ ] A、24[ ] B、36[ ] C、48[x] D、9328.Core Image能够操作哪些起源的图像数据?[多选题][x] A、Core Graphics[x] B、Core Data[x] C、Core Video[x] D、Image I/O29.每个CIFilter 滤镜对象至多有一个输出参数,并且产生一个输入图像?[判断题][x] A、正确[ ] B、谬误30.CIContext对象能够基于GPU,也能够基于CPU?[判断题][x] A、正确[ ] B、谬误31.当应用GPU进行渲染时,因为应用 OpenGL ES技术,所以能够取得比CPU更快的渲染速度,然而无奈在后盾进行操作?[判断题][x] A、正确[ ] B、谬误32.CIContext在默认状况下是应用GPU进行渲染的?[判断题][ ] A、正确[x] B、谬误33.CIContext在应用CPU渲染时,速度比GPU较慢,此时能够通过iOS的GCD技术在后盾进行渲染,从而晋升用户的体验吗。[判断题][x] A、能够[ ] B、不可34.CIDetector对象无奈在视频中 进行特色的搜寻和检测?[判断题][ ] A、正确[x] B、谬误35.自哪个版本的iOS开始,Apple为用户带了炫酷的毛玻璃成果?[单选题][ ] A、iOS 6.0[x] B、iOS 7.0[ ] C、iOS 8.0[ ] D、iOS 9.036.应用Core Image框架的哪些技术,能够实现人脸的检测?[多选题][x] A、CIFilter[x] B、CIdetector[x] C、CIFeature[ ] D、CIFrame37.CGImageRef、CGColorRef 两种数据类型是定义在哪个框架中的?[单选题][ ] A、Foundation[x] B、CoreGraphics[ ] C、UIKit[ ] D、Core Image38.QuartzCore框架和CoreGraphics框架是能够跨平台应用的,在iOS和mac OS`上都能应用?[判断题][x] A、正确[ ] B、谬误39.QuartzCore框架能够间接应用UIImage、UIColor?[判断题][ ] A、正确[x] B、谬误40.CADisplayLink是一个能让咱们以和屏幕刷新率雷同的频率将内容画到屏幕上的定时器?[判断题][ ] A、正确[x] B、谬误41.以下对于CADisplayLink和Timer,形容正确的是[多选题][x] A、CADisplayLink应用场合绝对专一,适宜做UI的不停重绘[x] B、NSTimer的应用范畴要宽泛的多,各种须要单词或者循环定时解决工作都能够应用。[x] C、在UI相干的动画或者显示内容应用CADisplayLink比起用 NSTimer的益处就是咱们不须要再分外关系屏幕的刷新频率。[x] D、CADisplayLink可用于自定义动画引擎或者视频播放的渲染。42.Core Animation动画框架能够用在iOS平台,无奈用在mac OS平台?[判断题][ ] A、正确[x] B、谬误43.Core Animation是能够间接作用在CALayer上的,所以它也能够作用在UIView上?[判断题][ ] A、正确[x] B、谬误44.Core Animation框架的动画执行过程都是在后盾操作的,不会阻塞主线程?[判断题][x] A、正确[ ] B、谬误45.对于Core Animation动画和UIView动画,以下说法正确的是:[多选题][x] A、Core Animation 动画 一切都是假象,并不会实在的扭转图层的属性。[x] B、如果在播放动画的时候,不须要与用户交互。举荐应用Core Animation动画。[ ] C、UIView动画一切都是假象,并不会实在的扭转图层的属性。[x] D、UIView动画必须通过批改属性的真实性,能力动画成果。46.CAAnimation是所有动画对象的父类,能够间接应用它,而无需应用它具体的子类:[判断题][ ] A、正确[x] B、谬误47.ARKit次要有哪三层核心技术?:[多选题][x] A、疾速稳固的世界定位,包含实时运算,静止定位[x] B、立体和边界感知 碰撞测试和光线估算,让虚构内容和事实环境无缝街接[x] C、反对各种渲染制作工具[x] D、反对各种三维模型制作工具48.iOS7带来的Sprite Kit框架反对哪些内容?:[多选题][x] A、精灵[x] B、场景[x] C、特效[x] D、物理库49.SceneKit能够与Core Image,Core Animation,SpriteKit 等已有的图形框架互相整合及合作吗?:[判断题][x] A、正确[ ] B、谬误50.Scene Kit反对以下哪些特效技术?:[多选题][x] A、粒子成果[x] B、物理引擎[x] C、脚本事件[x] D、多通道分层渲染51.Scene Kit框架是Cocoa下的3D渲染框架,它并不反对古老的Object-C语言?:[判断题][ ] A、正确[x] B、谬误52.Scene Kit提供了哪些类型的光照?:[多选题][x] A、环境光[x] B、定向光源[x] C、点光源[x] D、聚光灯53.对Scene Kit来说,Scean Kit的3D模型能够与2D精灵 混合应用吗?:[判断题][x] A、能够[ ] B、不能够54.对Scene Kit来说,Sprite Kit中的场景和纹理能够作为Scene Kit的纹理贴图吗?:[判断题][x] A、能够[ ] B、不能够55.第一个渲染pass永远是Scene Kit的默认渲染,它输入场景的哪些元素:[多选题][x] A、环境光[x] B、粒子成果[x] C、色彩[x] D、景深56.Scene Kit中的坐标系是右手坐标系,即笛卡尔坐标系吗?:[判断题][x] A、是的[ ] B、不是57.在iOS 8里,苹果公布了一个新的接口叫做 Metal,以下对Metal形容正确的是:[多选题][x] A、Metal 和 OpenGL ES类似,它也是一个底层API。[x] B、Metal负责和 3D绘图硬件交互。[x] C、Metal不是跨平台的。[x] D、Metal是一个GPU减速3D绘画的API。56.因为Metal十分底层,所以它容许你应用硬件达到运行效率的峰值,对你的游戏如何运行有着齐全的管制?:[判断题][x] A、正确[ ] B、谬误59.CAMetalLayer并不在Metal框架中,而是在以下哪个框架中:[单选题][ ] A、UIKit[x] B、QuartzCore[ ] C、Foundation[ ] D、Core Image

March 14, 2022 · 3 min · jiezi

关于ios:⑧网络篇史上最全iOS八股文面试题2022年金三银四我为你准备了iOS1000条笔试题以及面试题包含答案

iOS面试题 一共分为口试题和面试题两局部口试题 一共分为10个 总共613题面试题 一共400题 口试题 一个10个系列 别离为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ③(界面篇) 共83题 已更新 ④(iOS篇) 共52题 已更新 ⑤(操作篇) 共68题 已更新 ⑥(数据结构篇) 共23题 已更新 ⑦(多线程篇) 共60题 已更新 ⑧(网络篇) 共22题 已更新 ⑨(多媒体篇) 共59题 已更新 ⑩(平安篇) 共27题 已更新 面试题 一共分为3个 总共400题 ⑪(面试篇 1/3) 共127题 已更新 ⑪(面试篇 2/3) 共137题 已更新 ⑪(面试篇 3/3) 共136题 已更新 @TOC 口试题 613题⭐️⑧、口试题-网络篇(20题)1.iOS开发中,HTTPS通信是在什么地位来保障安全性的?:[单选题][ ] A、NSURLRequest办法里[ ] B、NSURLRequest代理办法里[ ] C、NSURLConnection办法里[x] D、NSURLConnection代理办法里2.对于NSURLConnection 同步通信和异步通信,上面说法正确的是?:[单选题][ ] A、同步通信是指发送数据后,不等接管方回应接着发下一个数据[ ] B、异步通信会阻塞以后线程[ ] C、发送同步通信时,零碎会主动创立一个独自的线程[x] D、个别不在主线程中应用同步通信,因为会引起主线程阻塞3.对于iCloud,上面说法谬误的是?:[单选题][ ] A、能够通过程序,将一个文档保留到用户的iCloud里[ ] B、用以通过程序,在iCloud里只保留一个键值对[ ] C、不能在模拟器上测试iCloud程序[x] D、程序应用iCloud时,只须要应用相应的API即可。不须要额定的配置4.应用程序大小超过多少时,只能通过WIFI从App Store上下载?:[单选题][ ] A、5MB[ ] B、10MB[x] C、20MB[ ] D、1000MB5.以下哪些Cocoa Touch框架,用于网络拜访?:[多选题][ ] A、OpenAL[x] B、Bonjour[x] C、WebKit[x] D、BSDSockets6.即时聊天app 不会采纳的网络传输方式是?:[单选题][ ] A、UDP[ ] B、TCP[ ] C、Http[x] D、FTP7.断点续传须要在申请头增加的管制续传最重要的关键字是?:[单选题][x] A、range[ ] B、length[ ] C、type[ ] D、size8.post传输的最大文件限度为?:[单选题][ ] A、1G[ ] B、2G[x] C、4G[ ] D、8G9.AFNetworking 网络框架是一个iOS开发中应用十分多的网络开源库,实用于以下哪些平台?:[多选题][x] A、iOS[x] B、mac OS[x] C、watch OS[x] D、tv OS10.以下对于HTTP协定,形容正确的是?:[多选题][x] A、GET 个别用于获取/查问资源信息[x] B、POST 个别用于提交/更新资源信息[x] C、PUT 个别用于减少资源信息[x] D、DELETE 个别用于删除资源信息11.对于中国的客户来说,Map Kit应用的是来自哪个平台的数据?:[单选题][ ] A、百度[x] B、高德[ ] C、谷歌[ ] D、苹果12.MKMapView能够实现哪些工作?:[多选题][x] A、显示指定地理位置的地图,如显示上海市的地图[x] B、设置地图的显示方式[x] C、在地图上对指定坐标地位做标记[x] D、反对地图的放大和放大13.Map Kit地图显示方式有哪几种?:[多选题][x] A、规范式的行政地图(会显示城市,街道等)[x] B、规范的卫星地图[x] C、卫星地图和混合地图(在卫星图上显示街道等名称)[x] D、高清的卫星地图14.默认状况下,calloutView 标注视图领有哪几个局部?:[多选题][x] A、题目[x] B、副标题[x] C、右辅助视图[x] D、左辅助视图15.在应用MKMapCamera相机时,须要设置 哪几个属性?:[多选题][x] A、相机在地图上的坐标[x] B、相机的察看方向[x] C、相机和地图之间的角度[x] D、以及相机在地图上方的高度16.MKMapCamera的heading属性为多少,示意地图顶部是正北方?:[单选题][x] A、0[ ] B、90[ ] C、180[ ] D、27017.MKMapCamera的pitch属性为多少,示意垂直往下看的角度,将产生规范的二维地图?:[单选题][x] A、0[ ] B、90[ ] C、180[ ] D、27018.在LaunchScreen.storyboard故事板中,不能应用UIWebView,因为这里是不能应用网络的:[判断题][x] A、正确[ ] B、谬误19.通过URL咱们能够定位一个近程web服务器上传的资源地位,然而无奈定位硬盘上的一个本地文件的门路?:[判断题][ ] A、正确[x] B、谬误20.如果须要取得一个网址中的参数,能够应用URL对象的哪些属性?:[多选题][x] A、parameterString[ ] B、scheme[x] C、query[ ] D、port21.当初的IM即时通讯 协定蕴含哪些?:[多选题][x] A、SIP : IETF的对话初始协定,是建设VOIP的连贯IETF规范,而VOIP就是网络电话。[x] B、SIMPLE : 即时通讯对话初始协定和示意扩大协定。[x] C、XMPP :基于 XML 且开发的扩大通信和示意协定。常称 Jabber协定。[x] D、PRIM : 显示和即时通讯协定。22.以下哪些是WKWebView的长处?:[多选题][x] A、领有 60fps 滚动刷新率[x] B、内置手势[x] C、高效的app 和 web 信息替换通道[x] D、和 Safari 雷同的 JavaScript 引擎

March 13, 2022 · 1 min · jiezi

关于ios:⑦多线程篇史上最全iOS八股文面试题2022年金三银四我为你准备了iOS1000条笔试题以及面试题包含答案

iOS面试题 一共分为口试题和面试题两局部口试题 一共分为10个 总共613题面试题 一共400题 口试题 一个10个系列 别离为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ③(界面篇) 共83题 已更新 ④(iOS篇) 共52题 已更新 ⑤(操作篇) 共68题 已更新 ⑥(数据结构篇) 共23题 已更新 ⑦(多线程篇) 共60题 已更新 ⑧(网络篇) 共22题 已更新 ⑨(多媒体篇) 共59题 已更新 ⑩(平安篇) 共27题 已更新 面试题 一共分为3个 总共400题 ⑪(面试篇 1/3) 共127题 已更新 ⑪(面试篇 2/3) 共137题 已更新 ⑪(面试篇 3/3) 共136题 已更新 @TOC 口试题 613题⭐️⑦、口试题-多线程篇(60题)1.上面办法中,哪个办法没有创立新的线程?:[单选题][ ] A、+(void)datechNewThreadSelector(SEL)selector,toTarget:(id)target withObject:(id)argument;[ ] B、- (id)initWithTarger(id)target selector:(SEL)selector object:(id)argument;[ ] C、- (void)preformSelectorInBackground(SEL)selector withObject:(id)arg;[x] D、- (void)preformSelectorInOnMianThread(SEL)selector withObject:(id)arg waitUntilDone:(BOOL)wait;2.Cocoa中的NSRunLoop类并不是线程平安的?:[判断题][x] A、正确[ ] B、谬误3.Run Loop的治理并不齐全是主动的:[判断题][x] A、正确[ ] B、谬误4.Run Loop同时也负责 autorelease pool的创立和开释?:[判断题][x] A、正确[ ] B、谬误5.GCD Queue分为哪三种?:[多选题][x] A、The main queue 主队列[x] B、Global queues 全局并发队列[x] C、用函数 dispatch_queue_create创立的用户队列[ ] D、Default queues 默认队列6.死锁有哪些必要条件?:[多选题][x] A、互斥[x] B、申请放弃[x] C、不可剥夺[x] D、环路7.以下哪种办法能够解决死锁:[多选题][x] A、鸵鸟策略[x] B、预防策略[x] C、防止策略[x] D、检测与解除死锁8.下列技术不属于多线程的是:[单选题][x] A、Block[ ] B、Thread[ ] C、Operation[ ] D、GCD9.线程和过程的区别不正确的是:[单选题][x] A、过程和线程都是由操作系统所领会的程序运行的根本单元[ ] B、线程之间有独自的地址空间[ ] C、过程和线程的次要差异在于它们是不同的操作系统资源管理形式[ ] D、线程有本人的堆栈和局部变量10.对于runloop的了解不正确的是:[单选题][ ] A、每一个线程都有其对应的RunLoop[ ] B、默认非主线程的RunLoop是没有运行的[x] C、在一个独自的线程中没必要去启用RunLoop[ ] D、能够将NSTimer增加到RunLoop中11.以下多线程对int型变量x的操作,哪个不须要进行同步:[单选题][ ] A、x=y[ ] B、x++[ ] C、++x[x] D、x=112.多线程中栈与堆是私有的还是公有的:[单选题][ ] A、栈私有,堆公有[ ] B、栈私有,堆私有[x] C、栈公有,堆私有[ ] D、栈公有,堆公有13.上面对于线程治理谬误的是:[单选题][ ] A、GCD所用的开销要比NSTread大[x] B、能够在子线程中批改UI元素[ ] C、NSOperationQueue是比NSThread更高层的封装[ ] D、GCD能够依据不同优先级调配线程14.Object C的线程上面形容不正确的是:[单选题][ ] A、应用NSThread创立、应用GCD的dispatch[x] B、间接应用NSOPeration,而后将其退出NSOPerationQueue[ ] C、在主线程执行代码,办法是performSelectorOnMainThread,[ ] D、如果想延时执行代码能够用performSelector:OnThread:withObject:waitUnitlDone;15.对NSOperationQueue了解不正确的是:[单选题][ ] A、寄存NSOperation的汇合类[ ] B、能够设置最大并发数[ ] C、放进去的线程会主动执行[x] D、用户须要治理放进去的线程执行程序16.以下对于iOS开发中多线程概念,形容正确的是:[多选题][x] A、Multthreadng多线程是指从软件或硬件上,试下多个线程并发执行的技术。[x] B、具备多线程能力的硬件,因为有硬件的反对。所以可能在同一时间内执行多于一个的线程,进而晋升应用程序的整体解决性能。[x] C、多线程可能同步实现多项工作,不是为了进步运行效率,而是为了进步资源应用效率,从而进步应用程序的效率。[x] D、过程启动之后,一个最次要的线程被称为主线程,主线程会创立和管理应用程序中所有的UI元素17.每个线程不仅仅在创立的过程中须要消耗工夫,同时它也会占用肯定内核的内存空间和应用程序的内存空间。:[判断题][x] A、正确[ ] B、谬误18.在iOS中,主线程的栈空间大小为:[单选题][x] A、1MB[ ] B、4MB[ ] C、8MB[ ] D、32MB19.在iOS中,主线程的栈空间大小是能够批改的?:[判断题][ ] A、正确[x] B、谬误20.在iOS中,应用程序子线程的默认栈空间大小为?:[单选题][ ] A、256 KB[x] B、512 KB[ ] C、1 MB[ ] D、4 MB21.iOS应用程序子线程的栈空间大小,会在线程的应用过程 逐步减少?:[判断题][x] A、正确[ ] B、谬误22.iOS子线程运行调配的最小栈空间是?:[单选题][ ] A、4 KB[ ] B、8 KB[x] C、16 MB[ ] D、32 MB23.子线程运行调配的栈空间大小,必须为4KB的整数倍?:[判断题][x] A、正确[ ] B、谬误24.线程的优先级属于threadPriority是一个0.0~1.0之间的浮点数,那么1.0示意 最高的优先级?:[判断题][x] A、正确[ ] B、谬误25.线程的默认的优先级是0.5?:[判断题][x] A、正确[ ] B、谬误26.优先级较高的线程,肯定比优先级较低的线程先执行?:[判断题][ ] A、正确x] B、谬误27.在线程 借鉴至沦亡的整个生命周期中蕴含多个状态,各状态的程序是?:[单选题][ ] A、创立状态、就绪状态、阻塞状态、运行状态、沦亡状态[x] B、创立状态、就绪状态、运行状态、阻塞状态、沦亡状态[ ] C、就绪状态、创立状态、运行状态、阻塞状态、沦亡状态[ ] D、就绪状态、创立状态、阻塞状态、运行状态、沦亡状态28.iOS应用程序的每条线程,都有惟一的RunLoop对象与之对应?:[判断题][x] A、正确[ ] B、谬误29.子线程的RunLoop须要手动创立?:[判断题][x] A、正确[ ] B、谬误30.主线程的RunLoop是主动创立并启动的?:[判断题][x] A、正确[ ] B、谬误31.子线程的RunLoop,当须要手动创立,调用以下哪个办法来启动:[单选题][ ] A、start()[ ] B、fire()[ ] C、new()[x] D、run()32.currentRunLoop是提早加载的,只创立一次?:[判断题][x] A、正确[ ] B、谬误33.应用Thread创立的线程,将共享同一应用程序的局部内存空间,它们领有对数据雷同的拜访权限?:[判断题][x] A、正确[ ] B、谬误34.为了协调多个线程对同一数据的拜访,通常的做法是拜访之前加锁.加锁会导致肯定的性能开销吗?:[判断题][ ] A、不会[x] B、会35.Thread的创立分为显式和隐式两种类型,其中显式形式有哪两种:[多选题][x] A、Thread.detachNewThreadSelector(selector:toTarger:with:)[ ] B、object.performSelector(inBackground:with:)[ ] C、object.performSelector(inBackground:afterDelay with:)[x] D、Thread.init(targer:selector:object:)36.当一个Lock对象胜利调用lock办法后,在其调用unlock办法之前,任何线程都不能对此Lock对象加锁:[判断题][x] A、正确[ ] B、谬误37.iOS提供了哪些类型的线程锁:[多选题][x] A、Lock[x] B、RecursiveLock[x] C、ConditionLock[ ] D、UnLock38.ConditionLock是一种带条件的锁,能够依据条件对多线程进行加锁?:[判断题][x] A、正确[ ] B、谬误39.也就是说一个线程能够对一个Recursive对象屡次调用lock,只有解锁时调用雷同的unlock办法便可。以上是RecursiveLock的特色吗?:[判断题][ ] A、不是[x] B、是40.因为线程是耗费系统资源的,所以须要控制线程的并发数,以防止零碎变慢?:[判断题][x] A、是[ ] B、不是41.Cocoa operation 相干的类有哪些:[多选题][x] A、Operation[x] B、NSLock[x] C、OperationQueue[x] D、NSThread42.为了在同一个工夫点内只执行一个线程,且以后一个线程完结后才执行第二个线程,须要将队列的maxConcurrentOperationCount设置为:[单选题][ ] A、0[x] B、1[ ] C、2[ ] D、1043.Grand Central Dispatch(GCD)是由Apple公司在哪个iOS版本时,推出的一个多核编程的解决方案:[单选题][x] A、iOS 4.0[ ] B、iOS 5.0[ ] C、iOS 6.0[ ] D、iOS 7.044.GCD的API很大水平上是和以下哪种技术配合应用的:[单选题][ ] A、delegate[x] B、block[ ] C、kvo[ ] D、kvc45.因为GCD基于工作单元而非像Thread那样基于运算,所以GCD能够管制 注入期待工作完结、监督文件描述符、周期执行代码以工作挂起等工作?:[判断题][x] A、正确[ ] B、谬误46.GCD的dispatch queue 调度队列能够是并发的,也能够是串行的?:[判断题][x] A、正确[ ] B、谬误47.以下对于并发、串行、同步和异步形容正确的是:[多选题][x] A、并发:多个工作同时执行[x] B、串行:一个工作执行实现后,再执行下一个工作[x] C、 同步:在以后线程中执行工作,不会开启新线程[x] D、 异步:在新的线程执行工作48.GCD的dispatch queue调度队列有以下哪三种类型?:[多选题][x] A、The main queues 串行队列[x] B、Global queues 全局队列[x] C、 用户线程队列[ ] D、 子线程队列49.Global queues 全局队列是并发队列,它蕴含哪些优先级?:[多选题][x] A、高[x] B、中[x] C、 低[x] D、 后盾50.Thead 多线程技术是基于什么来实现多线程的?:[单选题][x] A、Thead线程[ ] B、Queue队列[ ] C、 Block闭包[ ] D、Task工作51.Operation 多线程技术是基于什么来实现多线程的?:[单选题][ ] A、Thead线程[x] B、Queue队列[ ] C、 Block闭包[ ] D、Task工作52.Grand Cental Dispatch 多线程技术是基于什么来实现多线程的?:[单选题][ ] A、Thead线程[ ] B、Queue队列[ ] C、 Block闭包[x] D、Task工作53.Timer 定时器有哪两种性能?:[多选题][x] A、在指定的工夫执行指定的工作。[x] B、在指定的工夫范畴内执行指定的工作。[ ] C、 能够实现推送告诉的工作。[x] D、每隔一段时间执行指定的工作。54.以下放弃线程同步的形式有哪些?:[多选题][x] A、@synchronized[x] B、NSLock[x] C、NSCondition[x] D、pthread_mutex55.dispatch_semaphore是GCD用来同步一种形式吗?:[判断题][x] A、是[x] B、不是56.NSRecursiveLock是一个递归锁,这个锁能够被同一个线程屡次申请,而不会引起死锁吗?:[判断题][x] A、是[ ] B、不是57.OSSpinLock是一种自旋锁,它有哪三种办法?:[多选题][x] A、加锁[x] B、尝试加锁[ ] C、尝试解锁[x] D、解锁58.OSSpinLock 申请加锁失败的话,OSSpinLock会始终轮询,期待时会耗费大量CPU资源,所以OSSpinLock不适宜较长时间的工作?:[判断题][x] A、是[ ] B、不是59.NSLock 申请加锁失败的话,会先轮询,但一秒过后便会使线程进入 waiting状态。期待唤醒。以上说法正确吗?:[判断题][x] A、正确[ ] B、谬误60.pthread_mutex 是基于OC语言的多线程 加互斥锁的形式吗?:[判断题][ ] A、是[x] B、不是

March 12, 2022 · 2 min · jiezi

关于ios:被冰封的-BugFishhook-Crash-修复纪实

作者:郝连福,业界资深计算机技术专家,现任声网Agora 首席前端架构师。先后负责过 Principal Engineer/Engineering Director(UTStarcom)、Sr. architect(Intel)、T4 architect(YY)等职,曾设计开发电信核心网专用操作系统、高性能TCP/IP协定栈、以及声网SDK架构重构等重大项目。引言本文是声网Agora 与 RTC 开发者社区独特发动的 Dev for Dev(Developer for Developer)互动翻新实际流动的开篇,同时也是开源技术爱好者在一线工作中的实在记录。文中遇到的状况颇具代表性,特整顿分享进去以飨读者。 通常在 iOS 中实现利用 Hook 的形式有以下三种: 1.Method Swizzling:利用 OC(Objective C)的 Runtime 个性,动静扭转 SEL(办法编号)和 IMP(办法实现)的对应关系,达到 OC 办法调用流程扭转的目标,只实用于动静的 OC 办法; 2.Fishhook:FaceBook(现更名为 Meta)提供的一个动静批改链接 Mach-O 文件的工具,利用 Mach-O 文件加载原理,通过批改懒加载和非懒加载两个表的指针实现 C 函数 HOOK 的成果;实用于动态的 C 办法; 3.Cydia Substrate:原名为 Mobile Substrate,是一个弱小的框架,它的次要作用是针对 OC 办法、C 函数以及函数地址进行 HOOK 操作,实用于 OC 办法、C 函数以及函数地址,亦实用于 Android 平台。 Fishhook 是一个由 Meta 公司开源的第三方框架,它可能在模拟器和设施上动静地从新绑定运行在 iOS/macOS 上的 Mach-O 二进制文件的符号,从而实现动静批改 C 语言函数,罕用于利用的调试/追踪。这个框架只蕴含两个外围文件:fishhook.c 以及 fishhook.h 所以十分轻量,在许多企业级利用中颇受青眼。然而这个以简练著称的开源我的项目中,却埋藏着一个不易觉察的问题…… ...

March 11, 2022 · 2 min · jiezi

关于ios:⑥数据结构篇史上最全iOS八股文面试题2022年金三银四我为你准备了iOS1000条面试题包含答案

iOS面试题 一共分为口试题和面试题两局部口试题 一共分为10个 总共613题面试题 一共400题 口试题 一个10个系列 别离为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ③(界面篇) 共83题 已更新 ④(iOS篇) 共52题 已更新 ⑤(操作篇) 共68题 已更新 ⑥(数据结构篇) 共23题 已更新 ⑦(多线程篇) 共60题 已更新 ⑧(网络篇) 共22题 已更新 ⑨(多媒体篇) 共59题 已更新 ⑩(平安篇) 共27题 已更新 面试题 一共分为3个 总共400题 ⑪(面试篇 1/3) 共127题 已更新 ⑪(面试篇 2/3) 共137题 已更新 ⑪(面试篇 3/3) 共136题 已更新 @TOC 口试题 613题⭐️⑥、口试题-数据结构篇(23题)1.局部变量是保留在栈区的,办法调用的实参也是保留在栈区的?:[判断题][x] A、正确[ ] B、谬误2.栈是向低地址扩大的数据结构,是一块间断的内存的区域?:[判断题][x] A、正确[ ] B、谬误3.堆是向高地址扩大的数据结构,是不间断的内存区域吗?:[判断题][x] A、正确[ ] B、谬误4.栈是由零碎主动调配,速度较快,不会产生内存碎片?:[判断题][x] A、正确[ ] B、谬误5.堆是由alloc调配的内存,速度比较慢,而且容易产生内存碎片,不过用起来最不便?:[判断题][x] A、正确[ ] B、谬误6.int a;是指一个整型数(An integer):[判断题][x] A、正确[ ] B、谬误7.int *a;是指一个指向整型数的指针(A pointer to an integer) ?:[判断题][x] A、正确[ ] B、谬误8.int **a;是指一个指向指针的指针,它指向的指针是指向一个整型数?(A pointer to an integer to an integer) ?:[判断题][x] A、正确[ ] B、谬误9.int a[10],是指一个1有10个整型数的数组?:[判断题][x] A、正确[ ] B、谬误10.int *a[10],是指一个1有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointer to integers)?:[判断题][x] A、正确[ ] B、谬误11.int (*a)[10];是指一个指向有10个整型数数组的指针 (A pointer to an array of 10 integers)?:[判断题][x] A、正确[ ] B、谬误12.int (*a) (int) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(a point to a function that takes an integer as an argument and returns an integer)?:[判断题][x] A、正确[ ] B、谬误13.int (*a[10]) (int) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数 (An array of ten Pointers to a function that takes an integer argument and returns an integer)?:[判断题][x] A、正确[ ] B、谬误14.堆和栈的区别正确的是?:[单选题][ ] A、对于栈来讲,咱们须要手工管制,容易产生 memory leak[ ] B、对于堆来说。开释工作是由编译器主动治理,无需咱们手动治理。[ ] C、在Windows下,栈是向高地址扩大的数据结构,是间断的内存区域,栈顶的地址和栈的醉倒容量是零碎预先规定好的。[x] D、对于堆来来将,频繁的new/delete势必会造成内存空间的不间断,从而造成大量的碎片。使程序效率升高。15.上面四种外部排序算法中哪一种在最差状况 工夫复杂度最高?:[单选题][ ] A、疾速排序[x] B、冒泡排序[ ] C、堆排序[ ] D、归并排序16.上面的数据结构中不属于线性构造的是?:[单选题][ ] A、栈[ ] B、链表[x] C、二叉树[ ] D、线性表17.在一个二叉树上,第5层最多能够有多少个节点?:[单选题][ ] A、2[ ] B、8[x] C、16[ ] D、3218.在长度为n的线性表上进行程序查找,在最蹩脚的状况下须要的比拟次数是?:[单选题][x] A、n[ ] B、2n-1[ ] C、2n[ ] D、n^219.已知二叉树`后序遍历序列是dabec,中序遍历是debac,它的前序`遍历序列是?:[单选题][x] A、cebda[ ] B、acbed[ ] C、decab[ ] D、deabc20.多线程中栈与堆是私有的还是公有的:[单选题][ ] A、栈私有,堆公有[ ] B、栈私有,堆私有[x] C、栈公有,堆私有[ ] D、栈公有,堆公有21.求以下程序的输入int test(int x, int y){ x = x + y; return x y;}int main(int argc, const char argv[]){ @autoreleasepool { int x = 3, y = 10, z = test(x, y); NSLog(@"%d%d", x++, ++z); } return 0;} :[单选题][x] A、331 该题我在终端测试调试发现失去的答案曾经为3131 可能会跟编译器的位数无关[ ] B、330[ ] C、431[ ] D、43022.求以下程序的输入 int func(int x) {int countx = 0;while (x) {countx++; x = x&(x-1);}return countx;}int main(int argc,const char * argv[]){@autoreleasepool {NSLog(@"func %d",func(19999)); } :[单选题][ ] A、1[ ] B、5[ ] C、8[x] D、923.main(){ int a[5] = {1,2,3,4,5}; int prt=(int )(&a+1); printf("%d,%d",(a+1),(prt-1))}的答案是 :[单选题][ ] A、5,2[x] B、2,5[ ] C、1,4[ ] D、4,1

March 11, 2022 · 2 min · jiezi

关于ios:⑤操作篇史上最全iOS八股文面试题2022年金三银四我为你准备了iOS1000条笔试题以及面试题包含答案

iOS面试题 一共分为口试题和面试题两局部口试题 一共分为10个 总共613题面试题 一共400题 口试题 一个10个系列 别离为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ③(界面篇) 共83题 已更新 ④(iOS篇) 共52题 已更新 ⑤(操作篇) 共68题 已更新 ⑥(数据结构篇) 共23题 已更新 ⑦(多线程篇) 共60题 已更新 ⑧(网络篇) 共22题 已更新 ⑨(多媒体篇) 共59题 已更新 ⑩(平安篇) 共27题 已更新 面试题 一共分为3个 总共400题 ⑪(面试篇 1/3) 共127题 已更新 ⑪(面试篇 2/3) 共137题 已更新 ⑪(面试篇 3/3) 共136题 已更新 @TOC 口试题 613题⭐️⑤、口试题-操作篇(68题)1.在Instruments工具中,用于查看内存泄露的工具是:[多选题][ ] A、Counters[x] B、Allocations[x] C、Leaks[ ] D、Energy Log2.能够通过代码进行写操作的文件或目录有:[多选题][ ] A、bundle目录[x] B、Documents目录[x] C、keychain[x] D、SQLite3.应用Xcode创立工程时,反对同时创立的版本治理库是:[单选题][ ] A、Subversion[ ] B、Mercurial[x] C、Git[ ] D、Concurrent Versions System4.须要在手动治理内存调配和开释的Xcode我的项目引入和编译ARC格调编写的文件,须要在文件的Compiler Flags 增加参数:[单选题][ ] A、-shared[ ] B、-fon-objc-arc[x] C、-fobjc-arc[ ] D、-dynamic5.应用iPhone模拟器能够测试相机、传感器等性能?:[判断题][ ] A、正确[x] B、谬误6.以下哪个操作能够获取模拟器的截图?:[多选题][x] A、顺次点击[File > Save Screen Shot]菜单命令。[ ] B、应用[Command + D]快捷键。[x] C、应用[Command + S]快捷键。[ ] D、应用[Command + Shift + S]快捷键。7.应用Xcode9的模拟器,如果须要退出以后的应用程序,能够如何操作?:[多选题][x] A、应用[Command + Shift + H]快捷键。[x] B、应用[HardWare + Home]命令。[ ] C、应用[Command + Shift + E]快捷键。[x] D、点击模拟器的Home键。8.应用Xcode9的模拟器,如果须要革除模拟器中的所有应用程序,能够如何操作?:[单选题][ ] A、应用[HardWare + Restart]命令。[x] B、应用[HardWare + Erase All Content and settings...]命令。[ ] C、应用[File > Close Window]命令。[ ] D、应用[HardWare + Lock]命令。9.按下键盘上的哪个键,能够在模拟器中模仿双指触摸?:[单选题][ ] A、Command[x] B、Option[ ] C、Shift[ ] D、Control10.模拟器能够反对长按操作?:[判断题][x] A、正确[ ] B、谬误11.模拟器反对3D Touch操作?:[判断题][ ] A、正确[x] B、谬误12.程序单元是应用程序的最小可测试部件,最小可测试部件通常是包含基类、抽象类或者子类中的办法?:[判断题][x] A、正确[ ] B、谬误13.单元测试的要害组件是测试用例,测试用例能够在最低可测试的单元对代码进行测试?:[判断题][x] A、正确[ ] B、谬误14.XCTest框架能够进行单元测试,然而无奈进行性能测试?:[判断题][ ] A、正确[x] B、谬误15.Xcode的UI测试性能可能自动记录你在利用程序界面的每一个操作步骤,它能够将每一步的操作主动生成对应的代码吗?:[判断题][x] A、能够[ ] B、不能够16.应用Instruments提供的多种工具,能够对应用程序进行哪些操作?:[多选题][x] A、追究代码难以重现的问题。[x] B、对应用程序进行性能剖析。[x] C、对应用程序进行压力测试。[x] D、进行个别的零碎故障诊断。17.Instruments中的哪个工具,能够显示内存的对象占用曲线,内存以后调配给了哪些对象,被调配的对象数量,以及由哪些函数进行对象的创立?:[单选题][ ] A、Leaks[ ] B、System Trace[ ] C、Zombies[x] D、Allocations18.Instruments中的哪个工具,能够查看内存泄露的对象数量,每个泄露对象的类型,内存地址和占用大小等信息:[单选题][x] A、Leaks。[ ] B、System Trace。[ ] C、Zombies。[ ] D、Allocations。19.以下对于iOS开发的第三方依赖开源框架管理工具。说法正确的是:[单选题][x] A、SMP当初仅仅反对Swift语言,不反对iOS和watch OS平台。[x] B、Carthage 仅仅反对最低版本为iOS8的工程。[x] C、Cocoa Pods 则领有最多的开源框架反对,并且能够反对Swift和Objective-C两种语言编写的Cocoa工程。[x] D、Carthage是一个Swift编写的第三方依赖开源框架管理工具。20.应用CocoaPods 装置第三方开源框架之后。双击以下那个文件,来关上编辑装置后的我的项目。:[单选题][ ] A、projectName.xcodeproject[x] B、projectName.xcodeworkspace[ ] C、projectName.storyboard[ ] D、projectName.plist21.当减少或删除了某个第三方开源框架,或第一次减少Podfile到工程时,你须要应用以下哪个命令来装置框架?:[单选题][x] A、pod install[ ] B、pod update[ ] C、pod update --no-repo-update[ ] D、pod install --no-repo-update22.如果你的操作不须要更新podspecs,执行哪些命令能够疾速更新第三方开源框架?:[多选题][ ] A、pod update[x] B、pod update --no-repo-update[ ] C、pod install[x] D、pod install --no-repo-update23.Git的哪些指令须要在网络的环境中执行:[多选题][x] A、pull[x] B、commit[ ] C、status[x] D、push24.Git和SVN等其余版本控制系统的一个重要不同之处,就是Git有暂存区:[判断题][x] A、正确[ ] B、谬误25.Git版本有哪三种状态?:[多选题][x] A、commited[ ] B、updated[x] C、staged[x] D、modified26.Git中简直所有的操作都是可逆的?:[判断题][x] A、正确[ ] B、谬误27.能够为iPhone和iPad指定不同的`LaunchScreen.storyboard故事板?:[判断题][ ] A、正确[x] B、谬误28.LaunchScreen.storyboard故事版能够应用UIView或者UIViewController,而自定义的子类则不能够应用:[判断题][x] A、正确[ ] B、谬误29.写入SQLite数据库,从数据库中取出char类型,当char类型示意中文字符时,会呈现乱码,这是因为数据库的默认编码方式为:[单选题][x] A、ASCII[ ] B、UTF-8[ ] C、GB2312[ ] D、GBK30.以下哪条sqlite语句,能够执行非查问的sql语句?:[单选题][ ] A、sqlite3_open()[x] B、sqlite3_exec()[ ] C、sqlite3_step()[ ] D、sqlite3_close()Mac键盘快捷键阐明31.以下哪个快捷键,能够左移一行或多行选中的代码:[单选题][x] A、Command + [[ ] B、Command + ][ ] C、Command + <[ ] D、Command + >32.以下哪个快捷键,能够暗藏或显示左侧的我的项目的导航区:[单选题][ ] A、control +1[ ] B、control + 0[ ] C、command + 1[x] D、command + 033.以下哪个快捷键,能够暗藏或显示右侧的我的项目的工具区(Utilities):[单选题][x] A、Command + Alt + 0[ ] B、Command + Alt + 1[ ] C、Command + 0[ ] D、Command + 134.以下哪个快捷键,能够上移一行或多行抉择的我的项目的代码:[单选题][ ] A、Option + Command + <[ ] B、Option + Command + >[x] C、Option + Command + [[ ] D、Option + Command + ]35.以下哪个快捷键,能够新建一个我的项目?:[单选题][ ] A、 Command + Shift + A[x] B、Command + Shift +N[ ] C、Command + N[ ] D、Command + A36.以下哪个快捷键,能够新建一个文件?:[单选题][ ] A、 Command + Shift + A[ ] B、Command + Shift +N[x] C、Command + N[ ] D、Command + A37.以下哪个快捷键,能够在我的项目搜寻一个文件?:[单选题][x] A、 Command + Shift + F[ ] B、Command + Shift +S[ ] C、Command +F[ ] D、Command + S38.以下哪个快捷键,能够对以后我的项目执行Clear操作?:[单选题][ ] A、 Command + Shift + F[x] B、Command + Shift +K[ ] C、Command + Shift +H[ ] D、Command + Shift +N39.以下哪个快捷键,能够疾速编译并运行我的项目?:[单选题][ ] A、 Command + B[ ] B、Command + S[ ] C、Command + N[x] D、Command + R40.以下哪个快捷键,能够疾速对代码进行正文和勾销正文?:[单选题][x] A、 Command + /[ ] B、Command + \[ ] C、Command + C[ ] D、Command + T41.以下哪个快捷键,能够疾速在以后行插入或革除断点?:[单选题][ ] A、 Command + /[x] B、Command + \[ ] C、Command + C[ ] D、Command + T42.以下哪个快捷键,能够将光标疾速挪动到文件的头部?:[单选题][x] A、 Command + 上箭头[ ] B、Command + 下箭头[ ] C、Command + 左箭头[ ] D、Command + 右箭头43.以下哪个快捷键,能够将光标疾速挪动到文件的尾部?:[单选题][ ] A、 Command + 上箭头[x] B、Command + 下箭头[ ] C、Command + 左箭头[ ] D、Command + 右箭头44.以下哪个快捷键,能够将光标疾速挪动到行首?:[单选题][ ] A、 Command + 上箭头[ ] B、Command + 下箭头[x] C、Command + 左箭头[ ] D、Command + 右箭头45.以下哪个快捷键,能够将光标疾速挪动到行尾?:[单选题][ ] A、 Command + 上箭头[ ] B、Command + 下箭头[ ] C、Command + 左箭头[x] D、Command + 右箭头46.以下哪个快捷键,能够终止或模拟器的运行?:[单选题][ ] A、 Command + ,[x] B、Command + .[ ] C、Command + '[ ] D、Command + ~47.以下哪个快捷键,能够在同一行上将光标向右挪动?:[单选题][ ] A、 Control + M[ ] B、Control + B[x] C、Control + F[ ] D、Control + P48.以下哪个快捷键,能够在同一行上将光标向左挪动?:[单选题][ ] A、 Control + M[x] B、Control + B[ ] C、Control + F[ ] D、Control + P49.以下哪个快捷键,能够将光标挪动到前一行?:[单选题][ ] A、 Control + M[ ] B、Control + B[ ] C、Control + F[x] D、Control + P50.以下哪个快捷键,能够将光标挪动到后一行?:[单选题][x] A、 Control + N[ ] B、Control + B[ ] C、Control + F[ ] D、Control + P51.以下哪个快捷键,能够将光标挪动到本行的行首?:[单选题][ ] A、 Control + N[x] B、Control + A[ ] C、Control + F[ ] D、Control + P52.以下哪个快捷键,能够将光标挪动到本行的行尾?:[单选题][ ] A、 Control + N[ ] B、Control + A[x] C、Control + E[ ] D、Control + P53.以下哪个快捷键,能够删除 光标的字符?:[单选题][ ] A、 Control + N[ ] B、Control + A[ ] C、Control + E[x] D、Control + D54.以下哪个快捷键,能够删除光标所在行光标前面的代码,便于您重写行尾代码?:[单选题][ ] A、 Control + N[x] B、Control + K[ ] C、Control + E[ ] D、Control + D55.以下哪个快捷键,能够将显示区域挪动到光标显示的核心地位?:[单选题][ ] A、 Control + N[ ] B、Control + A[x] C、Control + L[ ] D、Control + D56.以下哪个快捷键,能够关上文件跳转列表,不便查看和关上历史文件?:[单选题][x] A、 Control + 1[ ] B、Control + 2[ ] C、Control + 3[ ] D、Control + 457.以下哪个快捷键,能够关上与以后文件处于同一文件夹下所有文件和文件列表?:[单选题][ ] A、 Control + 4[x] B、Control + 5[ ] C、Control + 6[ ] D、Control + 758.以下哪个快捷键,能够显示以后代码文件的所有办法列表?:[单选题][ ] A、 Control + 4[ ] B、Control + 5[x] C、Control + 6[ ] D、Control + 759.以下哪个快捷键,能够抉择光标右侧的代码?:[单选题][x] A、 Control + Shift + E[ ] B、Control + Shift + A[ ] C、Control + Shift + F[ ] D、Control + Shift + H60.以下哪个快捷键,能够抉择光标左侧的代码?:[单选题][ ] A、 Control + Shift + E[x] B、Control + Shift + A[ ] C、Control + Shift + F[ ] D、Control + Shift + H61.以下哪个快捷键,能够复制一个标签窗口?:[单选题][ ] A、 Command + A[ ] B、Command + E[x] C、Command + T[ ] D、Command + J62.以下哪个快捷键,能够关上辅助编译器?:[单选题][ ] A、 Command + Shift + Enter[ ] B、Command + Control + Enter[ ] C、Command + Enter[x] D、Command + Alt + Enter63.以下哪个快捷键,能够敞开关上辅助编译器?:[单选题][ ] A、 Command + Shift + Enter[ ] B、Command + Control + Enter[x] C、Command + Enter[ ] D、Command + Alt + Enter64.以下哪个快捷键,能够通过键入关键词的形式,疾速切换至某个文件?:[单选题][x] A、 Command + Shift + O[ ] B、Command + Shift + A[ ] C、Command + Shift + H[ ] D、Command + Shift + K65.CALayer、PDFDocument、NSImageRep,CIRenderTask,CIContext & CIImage这些类型的数据能够在哪个版本的Xcode间接看到数据内容,不再是简略的内存地址了?:[单选题][ ] A、 Xcode 6[ ] B、Xcode 7[ ] C、Xcode 8[x] D、Xcode 966.Xcode 9 中能够同时运行多个模拟器吗?:[判断题][x] A、 能够[ ] B、 不能够67.Xcode 9 中能够任意调节模拟器的显示比例吗?:[判断题][x] A、 能够[ ] B、 不能够68.Xcode 9 中反对哪些转换和重构:[多选题][x] A、 增加短少的协定要求[x] B、为形象办法增加短少的重写[x] C、提取到局部变量[x] D、提取办法/表达式Mac键盘快捷键阐明 ...

March 10, 2022 · 5 min · jiezi

关于ios:④iOS篇史上最全iOS八股文面试题2022年金三银四我为你准备了iOS1000条笔试题以及面试题包含答案

iOS面试题 一共分为口试题和面试题两局部口试题 一共分为10个 总共613题面试题 一共400题 口试题 一个10个系列 别离为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ③(界面篇) 共83题 已更新 ④(iOS篇) 共52题 已更新 ⑤(操作篇) 共68题 已更新 ⑥(数据结构篇) 共23题 已更新 ⑦(多线程篇) 共60题 已更新 ⑧(网络篇) 共22题 已更新 ⑨(多媒体篇) 共59题 已更新 ⑩(平安篇) 共27题 已更新 面试题 一共分为3个 总共400题 ⑪(面试篇 1/3) 共127题 已更新 ⑪(面试篇 2/3) 共137题 已更新 ⑪(面试篇 3/3) 共136题 已更新 @TOC 口试题 613题⭐️④、口试题-iOS篇(52题)1.iOS后盾运行时在哪个版本才开始反对的:[单选题][x] A、iOS3.0[ ] B、iOS4.0[ ] C、iOS5.0[ ] D、iOS6.02.下列UIView的办法中,哪一个在iOS5.0前后的零碎调用机制不同:[单选题][ ] A、addSubView[x] B、layoutSubView[ ] C、drawRect[ ] D、removeFromSuperView3.对于iOS程序后盾运行,上面说法正确的有:[多选题][x] A、程序能够在后盾播放音乐[x] B、程序能够在后盾收集用户地位信息[x] C、程序能够在后盾运行VOIP服务[x] D、程序能够在后盾发送HTTP通信4.对于iOS,以下说法正确的是?:[多选题][x] A、iOS是Apple公司推出的一款操作系统,是用于Apple挪动设施的挪动操作系统。[x] B、因为最后是设计给iPhone应用的,所以该零碎原名为iPhone OS 。即"iPhone 运行 OS X"。[x] C、iOS零碎应用了和macOS一样的Unix内核。[x] D、iOS零碎能够1利用在iWatch和iPod上。5.用户能够通过Siri技术,应用语言发问的形式进行人机交互。Siri的引入是从哪个iOS版本开始的?:[单选题][ ] A、iOS 4.0[x] B、iOS 5.0[ ] C、iOS 6.0[ ] D、iOS 7.06.从哪个iOS版本开始,零碎UI从拟物格调转换为扁平化格调:[单选题][ ] A、iOS 5[ ] B、iOS 6[x] C、iOS 7[ ] D、iOS 87.Apple Pay是在哪个版本开始和大家见面的?:[单选题][ ] A、iOS 6[ ] B、iOS 7[x] C、iOS 8[ ] D、iOS 98.从哪个iOS版本开始,苹果凋谢了对第三方输出的反对:[单选题][ ] A、iOS 7[x] B、iOS 8[ ] C、iOS 9[ ] D、iOS 109.Split View和画中画性能最早是在哪个iOS版本中引入的?:[单选题][ ] A、iOS 7[ ] B、iOS 8[x] C、iOS 9[ ] D、iOS 1010.针对中国用户,苹果在哪个iOS版本中,开始对电话性能进入了非常体贴的优化。减少骚扰电话辨认性能。:[单选题][ ] A、iOS 7[ ] B、iOS 8[ ] C、iOS 9[x] D、iOS 1011.ARKit加强事实性能和CoreML机器学习性能在哪个iOS版本中引入的?:[单选题][x] A、iOS 11[ ] B、iOS 10[ ] C、iOS 9[ ] D、iOS 812.对于iOS开发,以下说法正确的是?:[多选题][x] A、采纳iOS零碎的iPhone屏幕较小,只是把须要事实给用户的内容正当地组织在一块小小的屏幕上,所有须要设计者进行精心的设计和排版。[x] B、iOS采纳手指触摸的形式进行人机交互,所以要尽可能使按钮等交互控件的尺寸放弃在44点以上,以防止误操作。[x] C、运行iOS零碎的挪动设施,通常内存在512MB~2GB之间。用户须要在利用中正当地应用多媒体素材,保障利用不会因太耗内存而被零碎主动关掉。[x] D、作为运行在挪动设施上的利用,须要尽可能升高电量的耗费。比方及时敞开天文定位服务,缩小不必要的网络申请,尽量避免以轮询的形式工作。13.对于iOS开发,以下说法正确的是?:[多选题][x] A、一个App作为一个程序束bundle存在,App只能够拜访其余资源束之内的文件夹或其余资源文件。[x] B、在iOS中运行的利用,能够拜访挪动设施自带的减速计、陀螺仪、天文定位设施、蓝牙、相机等。[x] C、iOS利用很少应用菜单进行页面之间的跳转,而是通常采纳导航控制器或标签可控制器进行页面之间的导航。[x] D、iOS零碎中的利用。没有最小化和敞开按钮。用户通过按下设施底部的Home键,退出正在运行的利用。利用退出后依然在内存保留一段时间。14.ARC主动援用计数和iCloud是在哪个iOS版本中新增的?:[单选题][ ] A、iOS 7[ ] B、iOS 6[x] C、iOS 5[ ] D、iOS 415.哪个iOS版本减少了对Bit 64的反对 和引入了TextKit框架?:[单选题][x] A、iOS 7[ ] B、iOS 6[ ] C、iOS 5[ ] D、iOS 416.哪个iOS版带来了 Size Class和 Autolayout主动布局性能?:[单选题][ ] A、iOS 7[x] B、iOS 8[ ] C、iOS 9[ ] D、iOS 1017.3D Touch和Ipad分屏是在哪个iOS版本开始引入的:[单选题][ ] A、iOS 7[ ] B、iOS 8[x] C、iOS 9[ ] D、iOS 1018.苹果在哪个iOS版本中向开发者凋谢了SiriKit框架?:[单选题][ ] A、iOS 8[ ] B、iOS 9[x] C、iOS 10[ ] D、iOS 1119.作为推广ApplePay的一种策略,苹果在哪个iOS版本中,向开发者凋谢了NFC(Near field communication)性能?:[单选题][ ] A、Xcode 8[ ] B、Xcode 9[ ] C、Xcode 10[x] D、Xcode 1120.Core Image 图像处理框架是从哪个iOS版本起退出进来的?:[单选题][x] A、iOS 5[ ] B、iOS 6[ ] C、iOS 7[ ] D、iOS 821.自哪个版本的iOS开始,Apple为用户带来了炫酷的毛玻璃成果?:[单选题][ ] A、iOS 6.0[x] B、iOS 7.0[ ] C、iOS 8.0[ ] D、iOS 9.022.storyboard故事版性能是在哪个iOS版本公布的:[单选题][ ] A、iOS 4[x] B、iOS 5[ ] C、iOS 6[ ] D、iOS 723.苹果的iOS零碎采纳了哪些严格的平安机制:[多选题][x] A、代码签名[x] B、权限隔离[x] C、可信启动连x] D、沙盒执行环境24.为App设置关键词,如果关键词蕴含竞品的名称,则关键词会被屏蔽:[判断题][x] A、正确[ ] B、谬误25.为App设置关键词,关键字 不须要蕴含app的名称?[判断题][x] A、正确[ ] B、谬误26.如果App审核被拒的起因是Meta信息造成的。则不须要从新提交IPA`文件吗?[判断题][x] A、正确[ ] B、谬误27.在iOS App中实体物品的购买能够应用支付宝?[判断题][x] A、正确[ ] B、谬误28.下载安装量无论是在App Store还是在Google Play,都是导致App排名 回升或者上涨的次要因素?[判断题][x] A、正确[ ] B、谬误29.在100字符长度的关键字列表中,越靠前的关键字权重越大?[判断题][x] A、正确[ ] B、谬误30.以下哪种状况会导致审核失败?[多选题][x] A、利用呈现解体、加载失败等非常明显的Bug。[x] B、利用形容、截图等与利用性能重大不符。[x] C、谬误应用抽奖、竞拍等促销形式。[x] D、蕴含虚伪、误导用户的信息或性能。31.在App的题目、子标题、形容文字等呈现安卓或Android字样。有可能在审核导致App被拒吗?[判断题][ ] A、不可能[x] B、很有可能32.集体开发者账号能够在App Store公布金融利用吗?[判断题][ ] A、能够[x] B、不能够33.利用应用了公有API,会在审核时被拒吗?[判断题][x] A、会[ ] B、不会34.利用名称、安装包等中央蕴含test、demo等字样,会在审核时被拒吗?[判断题][x] A、会[ ] B、不会35.应用程序在审核时被拒,能够分哪两种状况?[多选题][x] A、Binary Rejected[x] B、App Rejected[x] C、Metadata Rejected[x] D、Game Rejected36.如果应用程序审核被拒并显示 Binary Rejected,此时须要从新上传IPA文件吗?[判断题][x] A、须要[ ] B、不须要37.如果应用程序审核被拒并显示 Metadata Rejected,此时须要从新上传IPA文件吗?[判断题][ ] A、须要[x] B、不须要38.除了从App Store下载,咱们还可从哪些渠道 装置一个App?[多选题][x] A、开发App时能够间接把开发中的利用装置进手机进行调试。[x] B、In-House 企业外部散发,能够间接装置企业负数签名后的APP。[x] C、AD-Hoc 相当于企业散发的限度版。[x] D、应用开发者证书打包,并将包装置在开发者证书指定的设施上。39.苹果对间断订阅抽成15%[判断题][x] A、正确[ ] B、谬误40.开发者能够间接回复用户在App Store中的评论吗?[判断题][x] A、能够[ ] B、不能够41.App名称、截图和预览中蕴含价格信息(收费、打折)将无奈上架App Store?[判断题][x] A、正确[ ] B、谬误42.iOS11之前 导航栏的默认高度为:[单选题][ ] A、32Pt[ ] B、48Pt[x] C、64Pt[ ] D、96Pt43.iOS11之后如果设置preferLargeTitles = YES,则导航栏的高度为:[单选题][ ] A、32Pt[ ] B、48Pt[ ] C、64Pt[x] D、96Pt44.在iOS11上,如果App启动时图标的周围呈现彩色,是因为图标的四角的圆角,并且四周为通明像素。:[判断题][x] A、正确[ ] B、谬误45.获取苹果举荐的App须要蕴含哪些因素:[多选题][x] A、品质为上:取得苹果举荐的首要的条件便是产品质量。[x] B、关注度:设计新鲜,明确本人能传播给用户什么内容,同时具备独特的吸引力[x] C、商业模式:适当的商业模式和价格,最好是和同类游戏相比有着独具一格的商业模式[x] D、通用性:对于各种规格设施的反对,各个地区的本地化46.App Store容许开发者上传几张应用程序的截图:[单选题][ ] A、3[ ] B、4[x] C、5[ ] D、647.在App Store中,应用程序刚公布的前24小时的下载量是最大的:[判断题][x] A、正确[ ] B、谬误48.以下哪个属性是iOS11开始引入的,用来管制safeAreaInsets是否加到layoutMargins上?:[单选题][ ] A、layoutMargins[ ] B、directionLayoutMargins[ ] C、PreservesSuperviewLayoutMargins[x] D、insetsLayoutMarginsFromSafeArea49.以下哪个属性是iOS8开始引入的,用于指定视图和它的子视图之间的边距:[单选题][x] A、layoutMargins[ ] B、directionLayoutMargins[ ] C、PreservesSuperviewLayoutMargins[ ] D、insetsLayoutMarginsFromSafeArea50.以下对于TestFlight形容正确的是:[多选题][x] A、应用TestFlight,你能够向测试人员公布你app的prerelease版本来收集反馈信息。[ ] B、TestFlight是一个必选性能,只有在应用它之后,能力提交app到App Store。[x] C、TestFlight是收费的。[x] D、TestFlight只反对了iOS平台的App,,每个开发者账号最多只能测试10款不同的App。51.在iOS 8里,苹果公布了一个新的接口叫做Metal,以下对Metal形容正确的是:[多选题][x] A、Metal和OpenGL ES类似,它也是一个底层API。[x] B、Metal 负责 和 3D绘图硬件交互。[x] C、Metal 不是跨平台的。[x] D、Metal 是一个反对GPU减速3D绘图的API。52.你的利用如果处于期待开发者公布(Pending Developer Release)状态,将无奈测试内购我的项目?[判断题][x] A、正确[ ] B、谬误

March 9, 2022 · 3 min · jiezi

关于ios:iOS应用性能数据采集原理和优化实践-详细版

作者简介刘徐兵(Alvin Liu),云智慧/开发经理。曾在高德、当当有多年大型App开发教训,在云智慧从事APM SDK研发工作5+年。对App开发和性能优化有深刻的钻研和实际。 iOS利用数据采集的根底 Objective-C Runtime1、音讯转发Objective-C语言扩大了C语言,扩大的外围在于引入了Runtime库,使Objective-C语言领有了面向对象和动静运行时的个性。而动静运行时机制的外围和体现是音讯转发机制。 Objective-C语言领有动静运行时的机制,办法的执行是在运行阶段决定的而不是在编译阶段决定的。而办法执行的本质是向对象发送了一个音讯,官网API为 objc_msgSend(void /* id self, SEL op, ... */ )objc_msgSend有2个罕用参数:id self 和 SEL op,用于标识对象和办法,即向某个对象发送了某个音讯。因而Objective-C的[instance method]调用会被编译器转换成C语言API objc_msgSend的调用。 以下音讯转发机制原理图从官网文档翻译而来: 音讯转发机制示例图 如上图所示,Objective-C的音讯转发流程中,在以后对象办法列表中找不到办法的实现时,运行时环境会顺次进行三个阶段的查找 第一阶段 对象在收到无奈解决的音讯时,首先调用所属类的下列类办法。 +(BOOL)resolveInstanceMethod:(SEL)sel{ //默认返回NO return NO;} +(BOOL)resolveClassMethod:(SEL)sel{ //默认返回NO return NO;}如果在其中找到了办法的实现,则进行音讯解决;否则就进入第二阶段。 第二阶段 在以后类里找不到该办法的实现时,运行时零碎尝试更换调用的对象,会调用如下办法 -(id)forwardingTargetForSelector:(SEL)aSelector{}如果在该办法中还找不到办法的实现,就进入第三阶段。 第三阶段 到这里是最初一个阶段,通过创立NSInvocation实例,将与未解决的音讯无关的细节封装起来,运行时零碎调用的接口为 -(void)forwardInvocation:(NSInvocation *)anInvocation{}该办法会沿着类的继承链始终往上调用,直至在NSObject的该办法中抛出doesNotRecognizeSelector:异样。 2、函数指针SEL是Objective-C语言的办法选择器,也就是selector的指针。再往底层去,每个办法SEL还对应着一个IMP函数指针,指向办法实现的首地址。官网API为: typedef id (*IMP)(id, SEL, ...); 有了它就能够间接执行IMP指向的函数(办法)了。 以上介绍了实践根底,上面介绍下基于Objective-C语言动静运行时的办法拦挡(Hook)操作。 Hook原理 Hook步骤应用Category个性往类中增加用于拦挡的办法SEL应用零碎runtime的接口(Swizzle)替换办法实现体(IMP)Hook应用示例图 如图所示,开发者调用原有办法时,会转发到拦挡的办法里,因替换了原办法与拦挡办法的入口地址(IMP),在拦挡办法执行完结时能调回原办法,对原有业务没有影响。 Hook回调函数难点:不是类的实例形式,不能用Category个性。 优化前: 全工程扫描,再拦挡。 毛病:只能在主线程中操作,扫描文件数和耗费的工夫与App的规模大小成正比。 回调函数拦挡优化步骤: 针对要应用protocol的零碎类应用Category个性增加拦挡办法拦挡设置delegate的setter办法,获取到delegate的实例针对获取到的delegate实例再进行回调办法拦挡 优化后 1、提早拦挡:在办法被调用时才被拦挡而且只拦挡一次 2、SDK的启动操作跟App的业务和规模无关,对App的影响降到最低 解体解码实际目标: 理解iOS解体解码原理 ...

March 9, 2022 · 1 min · jiezi

关于ios:如何让云音乐iOS包体积减少87MB

本文作者:大鹏 云音乐iOS客户端是自2013年开始的老我的项目,经验近十年的业务滚动倒退,从单体音乐APP倒退至今,多种业务加持,俨然曾经成为相似于平台级的巨型APP,并且包体积也随着业务的倒退越来越臃肿,影响用户的理论体验,甚至是品牌的口碑,在笔者开始优化之前云音乐在AppStore显示的包体积曾经达到了420MB之多,在这种状况下,团队开启了包体积优化的专项。 包体积优化是客户端开发的老命题了,基本上作为iOS开发同学多多少少都理解大体该怎么做,但随着苹果的倒退,一些原来可行的措施在新版本曾经不在实用,所以本篇文章则侧重于优化过程中的一些最新的实践经验,以及在大我的项目中是如何落地的,那么话不多说,上面就开始。 口径 在开始做优化之前,咱们首先须要摸清楚包体积的各种口径以及它们之间的关系,因为后续的一些优化措施会导致不同口径此消彼长的状况,所以首先要确定最终目标口径是什么。首先,咱们能够在苹果后盾看到本人APP具体的装置大小和下载大小的具体情况,还蕴含了不同的机型版本。 那么苹果后盾的下载大小和装置大小是如何生成的呢,请看下图,在上传后,苹果官网对对咱们上传的IPA包解包后,对二进制进行了DRM加密(此项也会导致包体积的增长)和AppThinning,AppThinning会依据不同的机型对原始包的资源和代码进行不同水平的裁剪,从而生成适配具体机型的版本。此外苹果还会生成一个蕴含选集的通用版本,但并没有啥理论用途。对于DRM和AppThinning此处不开展,文章开端有链接。 如上图所示,在上传前后咱们有三个指标: APP原始包体积: 上传前IPA解包后,理论APP的大小下载体积: AppStore中流量下载时提示框的大小装置体积: AppStore中APP详情中显示的大小在摸清了各指标的关系后,咱们最终抉择了用户感知最强的装置体积作为外围指标,以其作为最终目标进行优化。 剖析 尽管曾经确定了指标,但在优化之前,还须要对现状进行剖析,找到最大的劣化点,从而有针对性的进行优化,获取最大的收益比,那么下图就是云音乐iOS包的根本状况,能够看到红色的资源局部占到了一半以上的体积,而二进制则次之也占到了四分之一多,那么后续优化的侧重点能够放到资源和二进制源码。 资源 对于资源的解决其实形式就是惯例那么几种:资源清理、资源整顿、资源压缩、资源云端迁徙、资源合并等等,总之就是想尽一切办法去升高资源所占用的本地空间,上面简略介绍下咱们在云音乐所做的工作。 资源清理 在开始做整体的资源优化之前,第一步是须要清理曾经不在应用的资源,包含图片、配置文件、音视频等等,检测无用资源的次要思路就是通过动态检测判断资源是否有被援用,例如应用ImageName来判断图片是否被应用,当然线上检测的形式是更精确了,但在资源这里没有必要,不过云音乐作为老业务,应用图片的姿态也各式各样,例如援用的文件名不标准、未使AssetCatelog、手动拼接图片名称2x3x等问题,这就须要略微定制化的形式进行查找,排除异常情况,其余APP依据本身理论状况调整即可,思路都一样,网上也有现成工具。 云音乐通过几轮清理之后,先后清理图片等类型文件1200+,取得收益12+MB左右的原始包体积降落,还是比拟可观的。 资源整顿 资源整顿其实就是把适合的资源用适合的形式治理,这里次要指的就是Asset.car文件,家喻户晓,苹果自iOS7之后推出了AssetCatelog文件,帮忙开发者治理资源,其中最次要的就是图片资源,在编译之后会生成Asset.car文件并打入IPA包中,前文也说过,云音乐是老工程,所以还有局部资源图片是非Asset治理的形式,而应用Asset会给包体积带来收益,所以就须要对现有资源进行迁徙,应用Asset进行治理;但这里有个问题,为什么应用Asset会带来包体积收益呢? 要答复下面的问题,首先要从Asset的原理说起,在AssetCatelog的编译过程中,以ImageSet类型为例,首先会对Asset中的ImageSet类型图片进行无损压缩,并且会把多张ImageSet图片合成一张大图,故在编译后,是无奈通过bundle path的形式读取图片的,必须应用苹果的ImageName的API,因为它是通过坐标等形式,从合成后的大图中获取具体的图片信息的;那么这样做的益处就是,在压缩和合成的过程中会有图片体积的收益;然而通过咱们钻研,发现并不是所有图片都会有此收益,一些大体积的图片在通过无损压缩和合成后,产生的体积更大,咱们猜想这可能和合成大图无关,越小的图片收益的可能性越高。 另外就是动图最好不要应用ImageSet的类型,因为在压缩和合成的过程中动图会呈现问题,导致通过ImageName读取进去的数据不对,会产生无奈播放等问题;然而能够应用DataSet的类型,DataSet是不参加合成和压缩的,所以不会影响,对于其余的资源类型,个别也都能够应用DataSet的形式,而读取的时候应用NSDataAsset即可。那如何晓得Asset解决过的资源的状况呢,能够应用上面命令解析编译好的Asset.car,获取其中资源编译后的信息。 xcrun --sdk iphoneos assetutil --info Assets.car 从上图能够看到,对于Data类型的资源,是没有压缩的;而对于Image类型,是有标注出具体的压缩算法的,以及一些图片信息。另外在过程中咱们也发现,对于不同的图片苹果应用的压缩算法都是不同的,并且会被压缩成多份,这也是为什么咱们在把一部分资源从bundle中移入AssetCatalog中后,IPA体积还变大了的起因,但没关系,装置体积是会降落的,是因为应用Asset的最大的收益其实是来源于前文提到过的苹果的AppThinning,苹果的瘦身机制会把Asset.car依据不同的机型进行散发,例如1x2x3x都有不同应答的设施机型,所以尽管会被压缩成多份,但每台机器理论应用的只有一份,这也是为什么即使是IPA变大了,但其实装置体积会变小。 最初要说的是,因为没方法一个一个图片去进行Asset编译比照编译前后的大小,从概率来讲,更举荐小图(5k以内)以及有多版本(2x3x)的图片放入AssetCatalog治理,其余资源其实独自存储更自在,而非应用DataSet,因为独自存储更方便使用各种压缩伎俩而不放心会被苹果的解决而影响到,这个点在后续资源压缩会具体说到。 通过这项优化,云音乐iOS客户端迁徙各种尺寸的图片资源2400+,实现装置体积收益22+MB。 资源压缩 资源压缩很好了解,顾名思义就是对资源进行各种形式的压缩,在云音乐中最次要的资源就是图片,其余类型占比很小,常见的图片资源格局次要是png、apng、webp等,云音乐包里绝大部分图片也是以上几种格局;因为通过上一步的工作,简直所有图片都在AssetCatalog中治理,而上文也提到了苹果会对AssetCatalog的图片资源进行无损压缩,所以如果咱们自身对图片资源所施加的无损压缩是没有成果的,因为苹果会再压一遍,最终后果是以他为准。所以要在压缩这里拿到优化后果,就要实质性的升高图片的大小,那么就得做有损压缩。对于惯例图片格式,咱们应用了pngquant、tinypng等算法及工具进行压缩,在应用pngquant时,通过先后大数据样本测试,最终抉择80%的有损比率,因为此时是比率是收益曲线最高同时绝对图片品质影响较小的时候,但对于不同的工程这个曲线兴许是不一样的,因为每个工程的理论资源状况是有区别的,所以要自行去获取工程的数据,具体的做法是能够过脚本去尝试不同的压缩率并记录压缩后果从而造成一张曲线图。另外在咱们包里还有很多遗留的体积较大的webp动图,个别的形式都无奈进行压缩,通过肯定的调研最终发现谷歌官网提供了Webpmux能够对webp动图进行拆解和逐帧压缩以及合成,基于此咱们编写了一个能够压缩webp动图的脚本,实现了对webp动图的压缩。最终咱们把所有常见格局的图片压缩能力集成在一个大脚本中,对包内所有的图片资源进行压缩,此脚本对于后续防劣化也有用途。 通过此项,整体压缩各尺寸png图片5000+,apng动图100+,webp动图100+,总体收益42+MB(原始包体积)。 资源云端迁徙 在通过清理、整顿、压缩后,资源局部还是有不少包体积的占用,所以咱们启动了大资源云端迁徙专项,之所以是大资源是因为大资源带来的收益比最高,通过探讨,联合云音乐的理论状况,最终定下了50kb的基线,大于50kb则会被界定为大资源。咱们不是没有思考资源对立迁徙对立下载的计划,但从云音乐的体验以及老本层面思考,最终还是抉择以传统形式解决ROI高的局部。通过筛选后云音乐包内有150+的case合乎大资源的状况,其中85%以上是能够迁徙至云端的。对于资源是否要放在本地还是云端,咱们和设计同学独特制订了相干资源图片\动画的应用标准,纯技术资源则由技术同学判断。 在迁徙专项做完后,总体迁徙了100+的大资源,收益约在31+MB(原始包体积)。 资源合并资源合并其实次要是二点,一个是单个类似图片的去重,咱们花了肯定功夫应用类似图的剖析算法对云音乐所有的资源图片进行了检测,后果和咱们预期并不相符,实际上并没有太多类似的图片、包含icon,此局部并无收益。另外一个是AssetCatalog合并,联合云音乐的理论状况,此项也并无收益,次要是云音乐的资源目前是集中化治理。 二进制 每个APP程序最终都会被编译出一个主体二进制文件,所有的动态库依赖都会被链接进来,此局部的大小次要由代码量以及编译参数影响,下文的优化思路也是集中于缩小代码量以及优化编译参数。 无用代码检测 想要升高代码量,首先想到的就是清理无用代码,那么哪些代码又是无用的呢?这就有了无用代码检测,个别检测的形式分为线上动静检测和线下动态检测,动静检测的准确率要远高于动态检测,并且动态代码编译器曾经反对了一些裁剪形式,例如DeadCode优化;那么基于此咱们采纳了更精确的线上大数据动静检测,惟一的毛病就是获取数据的周期较长,须要上线运行。 最后咱们的想法是通过hook类初始化办法+initialize来判断某个类是否被应用,但这种计划有几个问题:第一是启动机会的问题,因为咱们应用了AB采样,那么必须在AB初始化后某个工夫点开启,那么AB初始化之前的类就没法记录,除非所有用户都记录,只是在上传的时候采样,但这样会影响未被灰度的用户;第二是+initialize自身调用机会的问题,并不是所有类的+initialize都会被调用。之后咱们采纳了另外一种计划,在OBJC中,每个类都有本人的元数据,在元数据中的一个标记位存储着本人是否被初始化,这个标记位不受任何因素影响,只有有被初始化就会打标记,在objc的源码中获取标记位的形式如下: struct objc_class : objc_object { bool isInitialized() { return getMeta()->data()->flags & RW_INITIALIZED; }} 但这个办法APP是无奈间接调用的,它是objc的办法;然而并不代表RW_INITIALIZED这个标记位的数据不存在,数据还是在的,所以咱们能够通过已有的接口以及能够浏览的源码信息来模仿上述代码,从而取得标记位数据确定某个类是否是初始化的,代码如下: ...

March 7, 2022 · 1 min · jiezi

关于ios:②常识篇史上最全iOS八股文面试题2022年金三银四我为你准备了iOS1000条笔试题以及面试题包含答案

iOS面试题 一共分为口试题和面试题两局部口试题 一共分为10个 总共613题面试题 一共400题 口试题 一个10个系列 别离为 ①(语法篇) 共147题 已更新 ②(常识篇) 共72题 已更新 ③(界面篇) 共83题 已更新 ④(iOS篇) 共52题 已更新 ⑤(操作篇) 共68题 已更新 ⑥(数据结构篇) 共23题 已更新 ⑦(多线程篇) 共60题 已更新 ⑧(网络篇) 共22题 已更新 ⑨(多媒体篇) 共59题 已更新 ⑩(平安篇) 共27题 已更新 面试题 一共分为3个 总共400题 ⑪(面试篇 1/3) 共127题 已更新 ⑪(面试篇 2/3) 共137题 已更新 ⑪(面试篇 3/3) 共136题 已更新 @TOC 口试题 613题⭐️②、口试题-常识篇(72题)1.iOS开发者账号中,最多可能增加多少台设施号:[单选题][ ] A、1009[x] B、100[ ] C、99[ ] D、9992.最多能够为每个内购我的项目创立多少个促销代码:[单选题][ ] A、1009[x] B、100[ ] C、99[ ] D、9993.MVC模式的M、V、C别离指:[单选题][ ] A、模态、视图、控制器[x] B、模型、视图、控制器[ ] C、模型、控制器。视图[ ] D、视图、模型、控制器4.UDID是由多少位十六进制字符串组成?:[单选题][ ] A、20[ ] B、30[x] C、40[ ] D、505.在iOS开发环境下,后缀.a的文件又叫做:[单选题][ ] A、可执行文件[ ] B、类文件[ ] C、头文件[x] D、动态库6.iPhone、iPad、iTouch应用的架构是:[单选题][x] A、arm[ ] B、i386[ ] C、x86[ ] D、IA-327.对于应用程序目录在更新、复原和更新过程的变动,上面说法谬误的是:[单选题][x] A、在备份过程中 /Library/Caches目录会被备份[ ] B、在应用程序更新过程中,/Documents目录会被保留[ ] C、在北美过程中/tmp目录将不会被备份[ ] D、在应用程序更新过程中,/Library/Preferences目录会被保留8.iPhone上,不能被应用程序间接调用的零碎程序是:[单选题][ ] A、通讯录[ ] B、短信[x] C、日历[ ] D、邮件9.应用程序大小超过多少时,只能通过WiFi从App Store下载:[单选题][ ] A、5M[ ] B、10MB[x] C、20MB[ ] D、100MB10.可上传至App Store的App利用最大体积是多少?:[单选题][x] A、4GB[ ] B、3GB[ ] C、2GB[ ] D、8GB11.对于XML和JSON,下列说法正确的有:[多选题][x] A、XML是一种相似HTML的语言,JSON是一种轻量级的数据交换格局[ ] B、XML是基于键值对(key/value)的构造[ ] C、JSON有DOMSAX两种解析形式[x] D、JSON和XML之间能够互相转换12.在Xcode上创立一个iOS工程,会主动增加进工程的frameworks有哪些:[多选题][x] A、UIKit.framework[x] B、Foundation.framework[x] C、CoreGraphics.framework[ ] D、CoreData.framework13.面向对象的个性不包含:[单选题][ ] A、封装[ ] B、继承[ ] C、多态[x] D、结构14.以下哪些是Cocoa Touch框架,用于数据管理办法:[多选题][x] A、Core Data[ ] B、Webkit[ ] C、Core Location[x] D、SQLite15.内存治理了解不正确的是:[多选题][ ] A、程序A里有一段内存被胜利申请实现之后,内存计数器就从0变成1(这个过程是alloc);[x] B、程序B里要应用已存在内存,那么内存计数器从1变成2(这个过程是retain或者copy);[ ] C、紧接着程序A不须要这个内存了,那么程序A就把这个内存计数器减1(这个过程叫release);[ ] D、当零碎发现这个内存计数器变为小于等于0.那么久调用垃圾回收程序把这段内存回收(这个过程叫dealloc);16.MVC长处不正确的是:[单选题][ ] A、低耦合性[ ] B、高重用性和可适用性[ ] C、较低的生命周期老本[x] D、代码高效率17.Shell中,将command1的输入作为command2的输出应该应用的命令是:[单选题][ ] A、command1 && command2[ ] B、command1 > command2[ ] C、command1 & command2[x] D、command1 | command218.上面哪项不是动静语言的个性:[单选题][ ] A、在运行时替换一个类[x] B、在运行时动静加载lib文件[ ] C、在运行时批改对象中的办法[ ] D、在运行时减少对象的办法19.上面哪个不属于对象数据序列化办法:[单选题][ ] A、JSON[ ] B、Property List[ ] C、XML[x] D、HTTP20.下列不属于iOS存储形式的是:[单选题][x] A、FileManager[ ] B、归档[ ] C、SQLite[ ] D、CoreData21.IP Phone的原理是什么:[单选题][ ] A、IPV4[ ] B、DHCP[x] C、IPV6[ ] D、DNS22.那个Xcode版本带来了Wireless Development 无线调试性能?:[单选题][ ] A、Xcode6[ ] B、Xcode7[ ] C、Xcode8[x] D、Xcode923.当开发者收费退出Apple开发者打算,以下说法正确的是?:[多选题][x] A、无奈应用beta版的iOS SDK[ ] B、能够应用beta版的iOS SDK[x] C、无奈向App Store公布你的产品[ ] D、能够向App Store公布你的产品24.当开发者收费退出Apple开发者打算并领取年费之后,以下说法正确的是?:[多选题][x] A、能够应用beta版的iOS SDK[ ] B、无奈进行真机测试[x] C、能够向App Store公布你的产品[ ] D、无奈向App Store公布你的产品25.对于退出付费的开发者打算,以下说法正确的是?:[多选题][x] A、集体开发者账号,每年99美元,能够在App Store公布产品或在100个iOS设施上进行测试。[x] B、公司开发者账号,每年99美元。能够在App Store公布产品或在100个iOS设施上进行测试。申请该类型的账号时.须要填写公司的邓白氏编码(®D-U-N-S® Number)[x] C、企业开发者账号,每年299美元。能够在企业外部进行无设施数量限度的散发[ ] D、企业开发者账号同样能够在App Store中公布产品。26.对于类的继承,以下说法正确的是?:[多选题][x] A、继承是在一些通用类的根底上结构、建设和裁减新类的最无效的伎俩。[x] B、继承简化了人们对事务的意识和形容。能清晰体现相干类之间的层次结构关系。[x] C、继承提供了软件复用性能。可能缩小代码的冗余度,减少程序的重复性。[x] D、继承通过减少一致性,来缩小模块间的接口和界面,大大增加了程序的易维护性。27.NSObject是一个根类,简直所有的类都是从它派生而来。然而根类并不领有其余类都有的alloc和init办法?:[判断题][ ] A、正确[x] B、谬误28.UIResponder能够让继承它的类响应挪动设施的触摸事件,因为可能有多个对象响应同一个事件,iOS将事件沿响应链向上传递?:[判断题][x] A、正确[ ] B、谬误29.对于MVC模式中的M、V、C三者之间的通信形式、以下形容正确的是?:[多选题][x] A、数据模型Model通过告诉Notification和键值察看KVO机制与控制器Controller间接通信。[x] B、控制器通过设置View的DataSource属性。设置视图的数据源。如UITableview。[x] C、视图View通过动作Action,Targer向视图控制器ViewController报告事件的产生,例如用户点击了视图。[x] D、视图View通过Delegate委托(代理),向视图控制器报告事件的发送。如UIAlertViewDelegate、UITextFieldDelegate。30.以下哪些技术能够实现iOS的数据长久化?:[多选题][x] A、Plist属性列表[x] B、对象归档[x] C、SQLite3[x] D、Core Data31.Core Data 反对哪些类型的长久化 数据存储形式?:[多选题][x] A、SQLiteStore[x] B、XMLStore[x] C、BinaryStore[x] D、InMemoryStore32.iOS设施反对哪些定位形式:[多选题][x] A、手机基站定位[x] B、WIFI定位[ ] C、北斗卫星定位[x] D、GPS定位33.手机基站定位特点是定位速度在几种定位形式中是最快的,并且耗电·最小·,常识误差范畴比拟大:[判断题][x] A、正确[ ] B、谬误34.WIFI定位的反对范畴比基站定位广:[判断题][ ] A、正确[x] B、谬误35.CPS定位的特点是耗电最多,定位速度也最慢。然而长处是定位的精度最高?:[判断题][x] A、正确[ ] B、谬误36.CLLocationManager定位的哪种精度罕用于周边的酒店、机场等类型的利用:[单选题][ ] A、KCCLocationAccuracyNearestTenMeters[x] B、KCCLocationAccuracyHundredMeters[ ] C、KCCLocationAccuracyKilometer[ ] D、KCCLocationAccuracyBest37.应用哪些工具能够进行天文编码和反编码:[单选题][ ] A、CLLocationManagerDelegate[ ] B、CLLocationManager[ ] C、CLLocation[x] D、CLGeocoder38.在iOS设施中,陀螺仪的主要用途在哪些:[多选题][x] A、通过陀螺仪配合GPS设施,手机的导航可能达到前所未有的水准。[x] B、和iPhone和iPad上的摄像头配合应用。加强拍摄时的防抖性。[x] C、陀螺仪相当于一个平面的鼠标。所以常常被用在赛车、战机类的游戏中。可通过摇摆设施来管制赛车和战机的方向[x] D、微信的摇一摇性能,通过摇摆手机能够匹配同一时段触发该性能的微信用户。39.陀螺仪次要蕴含那几个组件?:[多选题][x] A、陀螺仪帧[x] B、搁置轴[x] C、方向坐标系[x] D、转子40.减速计只能侦测物体的挪动行为,并不具备精准侦测物体角度扭转的能力?:[判断题][x] A、正确[ ] B、谬误41.陀螺仪能够侦测物体程度扭转的涨停,然而无奈计算物体挪动的强烈水平:[判断题][x] A、正确[ ] B、谬误42.在iOS开发中,陀螺仪和减速计的应用是通过哪个框架实现的?:[单选题][ ] A、Core Data[ ] B、Core Image[x] C、Core Motion[ ] D、Core Location43.CMMotionManager对象的accelerometerUpdateInterval属性的值为0.1,示意每秒钟更新多少次的减速计的状态?:[单选题][ ] A、1[x] B、10[ ] C、100[ ] D、100044.本地化的资源文件,在应用程序的Bundle中,会依据语言的不同拆散成不同的文件吗?:[判断题][x] A、正确[ ] B、谬误45.开发者能够将我的项目中的每一个文本、图标和图形文件等进行本地化解决,但无奈对音频、视频、Storeboard文件进行本地化解决?:[判断题][ ] A、正确[x] B、谬误46.对于App Store,如果用户按年订阅。开发者第一年取得受害的70%,如果第二年持续购买订阅服务,开发者就能够取得85%的收益?:[判断题][x] A、正确[ ] B、谬误47.在iTunes Connect治理平台,那个我的项目能够提供展现应用程序的下载量、用户活跃度、用户地区散布、设施类型、程序版本类型?:[单选题][ ] A、我的App[x] B、App剖析[ ] C、销售和趋势[ ] D、用户和职能48.形容应用程序的关键词,能够用来帮忙客户在App Store中搜寻到精准的后果。它的长度限度在多少字符以内?:[单选题][ ] A、50[x] B、100[ ] C、200[ ] D、50049.NSFileManager是用来治理和操作 文件、目录等文件系统相关联内容的类。它隶属于那个框架:[单选题][x] A、Foundation[ ] B、UIKit[ ] C、Core Data[ ] D、Core Motion50.蓝牙设施蕴含哪些工作状态:[多选题][x] A、筹备(standby)[ ] B、播送 (advvertising)[ ] C、监听扫描 (Scanning)[ ] D、已连贯 (Connected)51.蓝牙4.0反对哪些iOS版本:[多选题][ ] A、iOS4[x] B、iOS5[x] C、iOS6[x] D、iOS752.当向App Store上传IPA文件时,每次上传IPA包的版本号能够雷同,然而Build号不能雷同:[判断题][x] A、正确[ ] B、谬误53.上传至App Store的IPA文件, 最大体积是?:[单选题][ ] A、1G[ ] B、2G[x] C、4G[ ] D、8G54.利用审核胜利并公布后,你将无奈批改利用的分类、名称、截图和关键字?:[判断题][x] A、正确[ ] B、谬误55.利用审核胜利并公布后,你将无奈批改利用的促销文字、版权信息?:[判断题][ ] A、正确[x] B、谬误56.如果您须要给苹果审核人员写邮件,能够应用中文书写吗?:[判断题][x] A、能够[ ] B、不能够57.下载Xcode尽量别用迅雷,迅雷有可能会提供蕴含后门的Xcode:[判断题][x] A、正确[ ] B、谬误58.iOS的零碎架构能够分为那几个档次?:[多选题][x] A、外围操作系统层(Core OS layer)[x] B、外围服务层 (Core Services layer)[x] C、媒体层(Media layer)[x] D、可触摸层 (Cocoa Touch layer)59.如果App1须要跳转到App2,能够应用以下哪种形式?:[单选题][x] A、URL Scheme[ ] B、Keychain[ ] C、UIPasteboard[ ] D、UIDocumentInteractionController60.Core ML 机器学习框架反对哪些平台:[多选题][x] A、iOS[x] B、macOS[x] C、tvOS[x] D、watchOS61.Core ML 反对哪些机器学习技术?:[多选题][x] A、深度神经网络[x] B、循环神经网络[x] C、卷积神经网络[x] D、反对向量机62.Core ML 的已训练模型(trained model) 是指在对一组训练数据利用了某个机器学习算法后,所生成的一组后果吗?:[判断题][x] A、是[ ] B、不是63.Core ML 反对哪些机器学习模型:[多选题][x] A、Neural Network[x] B、Three Ensemble[x] C、Support Vector Machine[x] D、Generalized Linear Model64.Core ML 的运行须要哪种模式格局:[单选题][ ] A、.model[ ] B、.data[x] C、.mlmodel[ ] D、.plist65.以下哪项苹果推出的技术能够将自然语言的字符串标记为单词、确定词性和词根、划分出人名地名和组织名称、通知你字符串应用的语言和语系?[单选题][ ] A、Core Data[x] B、NSLinguisticTagger[ ] C、SirKit[ ] D、Core Text66.以下对于Predicate谓词,形容正确的是:[多选题][x] A、能应用个别谓词的不要应用正则表达式,以进步程序的性能。[x] B、尽量不应用嵌套,最好把条件拆分。[x] C、字符串常量应用"和""是一样的[x] D、关键字不辨别大小写,比方: tip和TIP是一样的。67.从在屏幕上点击你的app icon开始。到利用执行到main()办法或者执行到applicationWillFinishLaunching的过程中,共执行了哪些办法?:[多选题][x] A、dylib loading time 载入动静库。[x] B、ebase/binding time 重构和绑定。[x] C、ObjC setup time 在Objective-C的运行时(runtime),须要对类(class),类别(category)进行注册。[x] D、initializer time 这一份指代的是执行 +initialize办法的工夫。68.以下对于代码正文,说法正确的是:[多选题][x] A、最好的代码是不须要正文的 尽量通过正当的命名[x] B、良好的代码把含意表白分明 在必要的中央增加正文[x] C、正文须要与代码同步更新。[x] D、如果做不到命名尽量的见名知意的化。就能够适当增加一些正文或者mark69.以下对于iOS Code Review, 形容正确的是:[多选题][x] A、文件行数偏多,能够依据性能拆分为不同的文件,让每个类各司其职。[x] B、代码格调对立,比方函数名前面大括号的地位,放弃书写统一。[x] C、分支 if else 尽量配对应用。保障逻辑残缺。if外面尽量蕴含次要的解决逻辑。[x] D、查看代码的雷鸣、变量的命名格调是否对立。70.DateFormatter 这种比拟耗费性能的类,如果分配内存次数较多的话,须要做一个动态变量,没必要每次都调配?:[判断题][x] A、正确[ ] B、谬误71.应用程序在后盾个别能够运行多久?:[单选题][x] A、10秒左右[ ] B、1分钟左右[ ] C、10分钟左右[ ] D、1小时左右72.method swizzling 替换办法有几种实现形式:[多选题][x] A、利用 class_exchangeImplementations 替换两个办法的实现[x] B、利用 class_replaceMethod 替换办法[x] C、利用 method_exchangeImplementations 替换两个办法的实现[x] D、利用 method_setImplementation 来间接设置某个办法的IMP

March 6, 2022 · 3 min · jiezi

关于ios:iOS自动化测试驱动工具探索

本文次要介绍了字节 iOS 自动化测试驱动工具的摸索过程及实现原理作者:字节跳动终端技术——陈友辉 一、背景随着业务的扩张,单个 App 的性能越来越多,工程复杂度越来越高,每天MR可达上百次,代码变更可达上千处,航母级的 App 在这一点上更为严重。如何在频繁的代码变更中保障App品质,成了各个业务的痛点。靠传统的人工测试已无奈满足各业务的需要,咱们须要将更多的测试场景自动化。 自动化测试须要将人工交互行为变成自动化的原子操作。比方利用装置卸载、屏幕点拖拽及缩放、实体按键点击、设施信息获取、利用启停等等。这就须要一款工具来驱动 iOS 设施实现以上操作。这篇文章次要介绍字节 iOS 自动化测试驱动工具 bdc 的摸索过程及实现原理。 二、性能介绍在介绍 bdc 的摸索过程及实现原理之前,先介绍一下 bdc 的能力: 三、摸索历程晚期计划在字节开始大规模建设自动化建设时,Android 曾经有较为欠缺的解决方案,包含其生态自带的驱动工具 adb 及开源的云真机治理平台 STF。但 iOS 在这方面绝对滞后,次要是 iOS 短少一款相似 adb 功能齐全且稳固的驱动工具。 晚期 iOS 采纳了 Facebook 开源的计划,Facebook 在驱动工具方面先后开源了 wda 与 idb,wda 反对 UI 交互操作,idb 反对利用治理,这在肯定水平上满足了咱们的需要,基于这套计划,搭建了第一个版本的自动化测试机架。 晚期的机架也很简略,机器的规模也不大 通过一段时间的实际,咱们遇到了以下几个问题 wda 局部接口执行耗时较长,效率低下,无奈满足高频率调度的需要idb 很多命令只反对模拟器,对真机不够敌对,无奈满足咱们的性能扩大命令执行失败率高,工具稳定性差,且出问题后难以排查整套流程强依赖 Xcode 环境,规模化、自动化部署老本高,无奈应答上千台手机的部署工具改进UI 交互革新为了解决上述问题,咱们联合 wda 的实现思路,实现了一个更高效稳固的 XCTest 工具。咱们对 XCTest 相干的接口进行了review,并找到了XCTest 实现跨过程调用最底层的接口。通过这些接口,能够间接调用 testmanagerd 过程。随后基于这些底层接口封装了一套新的接口,能够实现屏幕的点拖拽、实体按键点击、文本输出等操作。相比 wda,在执行速度和稳定性上取得大幅晋升。 testmanagerd 过程是一个开发者守护过程,在 iOS 设施开启开发者模式后,testmanagerd 过程的镜像会被挂载到 iOS 设施零碎的 Developer 目录,并被 launchd 过程启动。XCTest 应用苹果自带的 XPC 机制与 testmanagerd 进行通信,利用 NSXPCConnection,只需晓得服务的 id 即可建设通信,testmanagerd 服务的 id 可在其镜像文件里找到。镜像的门路位于:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport ...

March 3, 2022 · 2 min · jiezi

关于ios:智能家居之战Home-Assistant智汀家庭云-谁更胜一筹

智能设施单品肯定要通过树莓派、 Homebridge装置Home Assistant来反对HomeKit才能够吗?并不是。像当初的绿米联创科技Aqara外,更是有想智汀家庭云实现对HomeKit管制,智汀君在技术哥哥的领导下,只用了繁难的代码就实现了用安卓手机管制HomeKit智能设施。 这一切都是因为智能单品接入了智汀家庭云! 一、与Home Assistant相比拟,智汀家庭云谁更胜一筹如果你有弱小的DIY能力、喜爱折腾各种智能产品,还想用各种智能产品打造出一套相对个性化的智能家居零碎,你肯定不能错过Home Assistant。 Home Assistant是一个开源平台,能够不便地连贯各种外部设备和组件,并且反对依照本人的需要对设施做自动化联动管制。 通过Home Assistant里的Home Bridge组件连贯智能设施与苹果Homekit,轻轻松松就能让Siri管制你的智能设施。 但它也是具备了相应的毛病:一是HomeKit是苹果官网智能家居平台,也能够说是苹果智能家居协定,也是软件工具包。所有能用于苹果,对于安卓客户不太敌对;二是国内市场来说苹果智能家居产品毕竟少,大家也很少据说HomeKit产品;三是苹果HomeKit中目前除了电视还没有其余家电认证,对于家电的管制比拟单薄。 智汀家庭云也是一个开源平台,但跟homeassistant不同的是,它是通过各种不同的品牌插件包, 能够发现、连贯和治理智能硬件设施,实现智能设施之间的互联互通、自动化管制、语音管制。 二、开发文档哪里找请参考:introduction | 智汀科技开发文档 (zhitingtech.com) 1) 开发工具以后版本实用于 Xcode 版本 Xcode 13 。如果您应用不同的 Xcode 版本,请查看之前的版本。此版本为仅应用 Swift 5 反对 iOS 13+。 2 ) 源码地址 Git Hub名称URL形容sa-ios-sdkhttps://github.com/zhiting-te...iOS源码gitee名称URL形容sa-ios-sdkzhiting-tech/sa-ios-sdkiOS源码3) 构建版本 克隆存储库bash $ git clone https://xxxx/sa-ios-sdk.gitCocoaPods装置CocoaPods,详情可查问introduction | 智汀科技开发文档 (zhitingtech.com),CocoaPods装置实现后,请用CocoaPods下载第三方库$ cd sa-ios-sdk$ pod install 如遇下载失败,则可能需迷信上网,自行配置网络代理。 运行程序pod install 胜利后,在模拟器中编译并运行应用程序。 如果您没有看到任何数据,请查看 "Simulator" -> "Debug" -> "Location" 以更改地位。 三、软件开源请参考:zhiting-tech/sa-ios-sdk 如果你想用通过智汀家庭云来开发本人的智能设施,如果你想理解更多智汀家庭云接入HomeKit的信息,欢送退出智汀微信公众号。 扫描下方二维码,连忙入群吧!  

February 25, 2022 · 1 min · jiezi

关于ios:iOS-自动化之atxserver

首先须要筹备一台iOS12以上的机子(在12以下的机子可能会无图像)、一台电脑(mac等都能够) 1.装置rethinkdb服务器并启动rethinkdb 2.首先依据https://github.com/openatx/at...网址装置好依赖,cd到atxserver2文件夹下,通过python3 main.py启动atxserver2 3.其次在iOS上启动须要其中最重要的设施治理依赖https://github.com/openatx/at...依据下面链接,装置好依赖,咱们这里抉择的是启动形式2:手动通过内部程序启动WDAcd到atxserver2-ios-provider目录下,执行python3 main.py --manually-start-wda 4.通过tidevice启动wda tidevice -u 3bab9b859a376ab5e6adab0ba94b1a38074fb2cc xctest -B com.facebook.WebDriverAgentRunner.xctrunner

February 22, 2022 · 1 min · jiezi

关于ios:智汀云盘开发指南iOS端文件夹管理

1. 文件夹列表: FolderManageViewController.swift /// 申请数据 private func requestData() { if folders.count == 0 { showLoading() } let page = (folders.count / 30) + 1 NetworkManager.shared.folderList(page: page, pageSize: 30) { [weak self] response in guard let self = self else { return } self.hideLoading() self.folders.append(contentsOf: response.list) self.collectionView.mj_header?.endRefreshing() self.collectionView.mj_footer?.endRefreshing() if !response.pager.has_more { self.collectionView.mj_footer?.endRefreshingWithNoMoreData() } self.collectionView.reloadData() } failureCallback: { [weak self] code, err in self?.collectionView.mj_header?.endRefreshing() self?.collectionView.mj_footer?.endRefreshing() self?.collectionView.reloadData() self?.hideLoading() self?.showToast(err) } } /// cell配置 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FolderManageCell.reusableIdentifier, for: indexPath) as! FolderManageCell let folder = folders[indexPath.row] cell.folder = folder /// menu按钮回调 cell.menuCallback = { [weak self] in guard let self = self, let cell = self.collectionView.cellForItem(at: indexPath) else { return } let x = 35.ztScaleValue let y = 50.ztScaleValue + Screen.k_nav_height let alertPoint = cell.convert(CGPoint(x: x, y: y), to: self.view) let alert = MenuAlert(items: [.init(title: "更改明码", icon: .assets(.icon_lock))], alertPoint: alertPoint) alert.selectCallback = { [weak self] item in guard let self = self else { return } if item.title == "更改明码" { let alert = FolderEditPwdAlert() alert.saveCallback = { [weak self] old, new, confrim in guard let self = self else { return } LoadingView.show() NetworkManager.shared.editFolderPwd(id: folder.id, oldPwd: old, newPwd: new, confirmPwd: confrim) { [weak self] _ in guard let self = self else { return } alert.removeFromSuperview() LoadingView.hide() SceneDelegate.shared.window?.makeToast("批改胜利".localizedString) self.reloadData() } failureCallback: { code, err in LoadingView.hide() SceneDelegate.shared.window?.makeToast(err) } } SceneDelegate.shared.window?.addSubview(alert) } } SceneDelegate.shared.window?.addSubview(alert) } /// 状态cover 按钮回调 cell.statusCoverCallback = { [weak self] index in guard let self = self else { return } switch folder.statusEnum { case .failToDelete: if index == 0 { // 批改文件夹失败 - 重试 self.showLoading() NetworkManager.shared.restartAsyncTask(task_id: folder.task_id) { [weak self] _ in guard let self = self else { return } self.hideLoading() self.reloadData() } failureCallback: { [weak self] code, err in self?.hideLoading() self?.showToast(err) } } case .failToEdit: if index == 0 { // 批改文件夹失败 - 确定 self.showLoading() NetworkManager.shared.deleteAsyncTask(task_id: folder.task_id) { [weak self] _ in guard let self = self else { return } self.hideLoading() self.reloadData() } failureCallback: { [weak self] code, err in self?.hideLoading() self?.showToast(err) } } default: break } } return cell }2. 文件夹设置: FolderManageSettingViewController.swift ...

February 15, 2022 · 5 min · jiezi

关于ios:智汀云盘开发指南iOS端存储池及存储池分区

1.存储池在我的页面,若该用户为拥有者,则可呈现存储池入口,拥有者可操作存储池的权限。 文件门路:ThirdParty/StorageManage/StorageManageViewController.swift 列表数据依据服务器获取,顶部数据为SA的外接硬盘数据,下局部则为云端创立的存储池数据。 private func reloadData() { let semaphore = DispatchSemaphore(value: 1) if hardDisks.count == 0 && storagePools.count == 0 { showLoading(.custom(.white_ffffff)) } DispatchQueue.global().async { semaphore.wait() /// 获取限度硬盘列表 NetworkManager.shared.hardDiskList { [weak self] response in guard let self = self else { return } self.hardDisks = response.list semaphore.signal() } failureCallback: { code, err in semaphore.signal() } /// 挂起工作,期待硬盘列表后果 semaphore.wait() /// 获取存储池列表 /// 传0间接获取全副数据 不分页 NetworkManager.shared.storagePoolList(page: 0, pageSize: 0) { [weak self] response in guard let self = self else { return } self.storagePools = response.list semaphore.signal() } failureCallback: { code, err in semaphore.signal() } /// 挂起工作,期待存储池列表后果 semaphore.wait() DispatchQueue.main.async { self.collectionView.mj_header?.endRefreshing() self.collectionView.reloadData() self.hideLoading() semaphore.signal() } } }1.1 增加存储池文件门路:ThirdParty/StorageManage/AddToStoragePoolViewController.swift ...

February 15, 2022 · 3 min · jiezi

关于ios:智汀云盘开发指南iOS文件夹加密逻辑

1.加密文件夹—加密过程1.文件夹的创立可设置私人文件夹及加密过程: 2.拜访服务器接口,创立私人文件夹 NetworkManager.shared.createFolder(name: name, pool_name: pool_name, partition_name: partition_name, is_encrypt: is_encrypt, pwd: pwd, confirm_pwd: confirmPwd, mode: mode, auth: members) { [weak self] _ in self?.showToast("保留胜利".localizedString) self?.navigationController?.popViewController(animated: true) } failureCallback: { [weak self] code, err in self?.hideLoading() self?.showToast(err) }3.创立给可拜访用户后可在该用户的文件列表内展现。 2.加密文件夹—解密过程1.文件列表数据Model中属性is_encrypt 为 1 时,则为加密文件或文件夹 2.加密文件夹款式的辨别。 3.加密文件夹进入的逻辑如下 tableview点击相应代理办法,具体参考MyFileViewController.swift if file.is_encrypt == 1 {//加密文件 //存储的明码对象 let key = AreaManager.shared.currentArea.scope_token + file.path let pwdJsonStr:String = UserDefaults.standard.value(forKey: key) as? String ?? "" let pwdModel = PasswordModel.deserialize(from: pwdJsonStr) if pwdModel != nil { //计算时间差 let timeTemp = TimeTool.TimeInterval(FromTime: pwdModel!.saveTime) if timeTemp > 72 {//大于72小时 //从新输出明码 pushToFolder(isNeedPwd: true, file: file) }else{ //无需输出明码 pushToFolder(isNeedPwd: false, file: file) } }else{ //须要从新输出明码 pushToFolder(isNeedPwd: true, file: file) } }else{ //无需输出明码 pushToFolder(isNeedPwd: false, file: file) } private func pushToFolder(isNeedPwd:Bool,file:FileModel){ let vc = FolderViewController() vc.currentPath = file.path vc.currentPaths = ["文件",file.name] vc.encrytRootFile = file vc.isWriteRoot = (file.write == 1) let key = AreaManager.shared.currentArea.scope_token + file.path if file.is_encrypt == 1 { vc.rootPasswordKey = key }else{ vc.rootPasswordKey = "" } if isNeedPwd { //存储文件夹根目录Key self.tipsTestFieldAlert = TipsTestFieldAlertView.show(message: "请输出明码", sureCallback: { pwd in print("明码是\(pwd)") NetworkManager.shared.decryptFolder(name: file.path, password: pwd) {[weak self] response in guard let self = self else {return} //存储工夫和明码 let pwdModel = PasswordModel() pwdModel.password = pwd //以后工夫 let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" pwdModel.saveTime = dateFormatter.string(from: Date()) UserDefaults.standard.setValue(pwdModel.toJSONString(prettyPrint:true), forKey: key) //解密胜利,进入文件夹 let nav = BaseNavigationViewController(rootViewController: vc) nav.modalPresentationStyle = .fullScreen nav.transitioningDelegate = self.transitionUtil self.navigationController?.present(nav, animated: true, completion: nil) } failureCallback: { code, err in self.showToast(err) } }) }else{ //无需输出明码 let nav = BaseNavigationViewController(rootViewController: vc) nav.modalPresentationStyle = .fullScreen nav.transitioningDelegate = transitionUtil self.navigationController?.present(nav, animated: true, completion: nil) } }加密文件夹进入子集目录需携带最后加密的文件,不便获取门路以及明码解密过程逻辑如下:(其中规定依据本身我的项目的需要来定,本我的项目以超出72小时则主动生效为准则,所以需存储首次解密的工夫)  ...

February 14, 2022 · 2 min · jiezi

关于ios:智汀云盘开发指南iOS文件列表及权限说明

1.文件列表1.1 我的文件——MyFileViewController.swift 数据获取——通过SA接口获取数据 NetworkManager.shared.fileList(path: "/", page: page, page_size: 30) { [weak self] response in guard let self = self else { return } LoadingView.hide() self.tableView.mj_header?.endRefreshing() self.tableView.mj_footer?.endRefreshing() //删选没有可读权限的文件 let datas = response.list.filter({$0.read != 0}) if isReload {//下拉刷新 or 首次加载数据 if datas.count == 0 { self.tableView.mj_footer?.isHidden = true self.tableView.reloadData() }else{ self.emptyView.removeFromSuperview() self.currentDatas = datas self.tableView.reloadData() } }else{//上拉加载更多数据 if !response.pager.has_more {//已无数据 self.tableView.mj_footer?.endRefreshingWithNoMoreData() self.isGetAllData = true return } self.isGetAllData = false self.currentDatas += datas self.tableView.reloadData() } } failureCallback: {[weak self] code, err in guard let self = self else { return } LoadingView.hide() self.tableView.mj_header?.endRefreshing() self.tableView.mj_footer?.endRefreshing() if self.currentDatas.count == 0 { self.tableView.addSubview(self.emptyView) self.emptyView.snp.makeConstraints { $0.center.equalToSuperview() $0.width.equalTo(Screen.screenWidth) $0.height.equalTo(ZTScaleValue(110)) } }else{ self.emptyView.removeFromSuperview() } self.showToast("\(err)") }此页面无抉择性能点击文件夹进入本人目录 let vc = ChangeFolderPlaceController() let nav = UINavigationController(rootViewController: vc) nav.modalPresentationStyle = .fullScreen self.present(nav, animated: true, completion: nil)1.2 共享文件——ShareFileViewController.swift ...

February 12, 2022 · 4 min · jiezi

关于ios:智汀云盘开发指南iOS快速上手

1.开发工具以后版本实用于 Xcode 版本 Xcode 13 。如果您应用不同的 Xcode 版本,请查看之前的版本。此版本为仅应用 Swift 5 反对 iOS 13+。 2. 源码地址1.Git Hub 名称URL形容zhiting-nas-ioshttps://github.com/zhiting-te...iOS源码2.gitee 名称URL形容zhiting-nas-ioshttps://gitee.com/zhiting-tec...iOS源码3. 构建版本克隆存储库bash $ git clone https://xxxx/sa-ios-sdk.gitCocoaPods装置CocoaPods,详情可查问CocoaPods CocoaPods装置实现后,请用CocoaPods下载第三方库 $ cd sa-ios-sdk$ pod install如遇下载失败,则可能需迷信上网,自行配置网络代理。 运行程序pod install 胜利后,在模拟器中编译并运行应用程序。 如果您没有看到任何数据,请查看 "Simulator" -> "Debug" -> "Location" 以更改地位。

February 12, 2022 · 1 min · jiezi

关于ios:collectionView-minimumLineSpacing-和-minimumInteritemSpacing

这两个属性和collectionView的滚动方向有关系:滚动方向雷同的间距为minimumLineSpacing  垂直的minimumInteritemSpacingcell排列程序:  和滚动方向垂直(以左上角为基准)顺次排列   程度滚动:从上到下 顺次排列  垂直滚动:从左到右顺次排列例子: // line 跟滚动方向雷同的间距  // item 跟滚动方向垂直的间距 flowLayout.minimumLineSpacing = 40;  flowLayout.minimumInteritemSpacing = 100; 垂直滚动                                                     程度滚动 总结就是:minimumLineSpacing :跟滚动方向统一的间距,例如垂直滚动,就是高低的间距,程度滚动就是,就是左右的间距。minimumInteritemSpacing :跟滚动方向垂直的间距,例如垂直滚动,就是左右的间距,程度滚动就是,就是高低的间距。

February 8, 2022 · 1 min · jiezi

关于ios:Swift-中的类与结构体

Swift中,类和构造体有许多相似之处,但也有不同本,文联合源码探索类和构造体的实质。 咱们都晓得,内存调配能够分为堆区(Heap)和栈区(Stack)。因为栈区内存是间断的,内存的调配和销毁是通过入栈和出栈操作进行的,速度远高于堆区。堆区存储高级数据类型,在数据初始化时,查找没有应用的内存,销毁时再从内存中革除,所以堆区的数据存储不肯定是间断的。并且 retain 操作不可避免要遍历堆,而Swift的堆是通过双向链表实现的,实践上能够缩小retain时的遍历,把效率进步一倍,然而还是比不过栈,所以苹果把一些放在堆里的类型改成了值类型,比方字符串、数组、字典等等。 其中,类(class)和构造体(struct)在内存调配上是不同的,根本数据类型和构造体默认调配在栈区,而类存储在堆区,且堆区数据存储不是线程平安的,在频繁的数据读写操作时,要进行加锁操作。 构造体除了属性的存储更平安、效率更高之外,其函数的派发也更高效。因为构造体的类型被 final 润饰,不能被继承,其外部函数属于动态派发,在编译期就确定了函数的执行地址,其函数的调用通过内联(inline)的形式进行优化,其内存间断,缩小了函数的寻址过程以及内存地址的偏移计算,其运行相比于动静派发更加高效。 另外,援用技术也会对类的应用效率产生耗费,所以在可选的状况下应该尽可能的应用构造体。 1、类和构造体的异同相同点: 都能定义属性、办法、初始化器;都能增加extension扩大;都能遵循协定;不同点: 类是援用类型,存储在堆区;构造体是值类型,存储在栈区。类有继承个性;构造体没有。类实例能够被屡次援用,有援用计数。构造体没有援用计数,赋值都是值拷贝。类有反初始化器(deinit)来开释资源。类型转换容许你在运行时检查和解释一个类实例的类型。2、值类型 vs 援用类型构造体是值类型,实际上,Swift 中所有的根本类型:整数,浮点数,布尔量,字符串,数组和字典,还有枚举,都是值类型,并且都以构造体的模式在后盾实现。 这意味着字符串,数组和字典在被赋值到一个新的常量或变量,或者它被传递到一个函数或办法中的时候,其实是传递了值的拷贝。这不同于 OC 的 NSString,NSArray 和 NSDictionary,他们是类,属于援用类型,赋值和传递都是援用。 值类型存储的是值,赋值时都是进行值拷贝,相互之间不会影响。而援用类型存储的是对象的内存地址,赋值时拷贝指针,都是指向同一个对象,即同一块内存空间。 构造体是值类型struct Book { var name: String var high: Int func turnToPage(page:Int) { print("turn to page \(page)") }}var s = Book(name: "程序员的自我涵养", high: 8)var s1 = ss1.high = 10print(s.high, s1.high) // 8 10这段代码中初始化构造体high为18,赋值给s1时拷贝整个构造体,相当于s1是一个新的构造体,批改s1的high为10后,s的age依然是8,s和s1互不影响。 通过 lldb 调试, 也可能看出 s 和 s1 是不同的构造体. 一个在 0x100008080, 一个在 0x100008098. (lldb) frame variable -L s0x0000000100008080: (SwiftTest.Book) s = {0x0000000100008080: name = "程序员的自我涵养"0x0000000100008090: high = 8}(lldb) frame variable -L s10x0000000100008098: (SwiftTest.Book) s1 = {0x0000000100008098: name = "程序员的自我涵养"0x00000001000080a8: high = 10}类是援用类型class Person { var age: Int = 22 var name: String? init(_ age: Int, _ name: String) { self.age = age self.name = name } func eat(food:String) { print("eat \(food)") } func jump() { print("jump") }}var c = Person(22, "jack")var c1 = cc1.age = 30print(c.age, c1.age) // 30 30如果是类,c1=c的时候拷贝指针,产生了一个新的援用,但都指向同一个对象,批改c1的age为30后,c的age也会变成30。 ...

February 7, 2022 · 9 min · jiezi