当开发被我们经常遇到这样的需求:在UITextField或者UITextView中限制用户可以输入的极度老字符数。如果是纯粹英文的输入,很好解决。但是遇到中文输入法,就会赶上各种坑,而且iOS系统自带的汉语输入法和老三正在输入法(搜狗,百度)也要是区分对待,emoji表情也是独十分坑,搞不好就截取错误,导致emoji表情显示错误。

一. 背景

hdfs,map-reduce,spark,yarn是蛮数量处理的根底零部件。在发展了几年后,已经化为了较通用的数据处理工具。记得几年前搭建hadoop这同学需要多少龙才会成功,现在由工具的逾提升,搭建完整的集群+监控系统只待多少钟头即可。

下面我们来看看哪些填写坑。

二. Ambari介绍

【Ambari】大凡apache的一个开源项目。就
Ambari 的意吧,就是创造、管理、监视 Hadoop 的集群。Ambari
自身为是一个分布式架构的软件,主要由于个别部分构成:Ambari Server 和 Ambari
Agent。简单来说,用户通过 Ambari Server 通知 Ambari Agent
安装相应的软件;Agent 会定时地发送各个机器每个软件模块的状态为 Ambari
Server,最终这些状态信息会显现于 Ambari 的
GUI,方便用户了解及集群的各种状态,并展开对应的掩护。HDP 2.2 所支撑的
Service 已经发生 18 单的多,分别是
Falcon,Flume,Hbase,HDFS,Hive,Kafka,Kerberos,Knox,Oozie,Pig,Ranger,Slider,Spark,Sqoop,Stom,Tez,Yarn,Zookeeper。现阶段风行的版本是HDP2.4

1.纯英文

正巧开自我是这么处理的,代码如下

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // Prevent crashing undo bug – see note below.
    if(range.length + range.location > textField.text.length)
    {
        return NO;
    }

    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    return newLength <= 25;
}

以此艺术是UITextField的代理方,作用如下:
打探代理于range克外的文本是否要替换为replacementString,Yes就替换,反的便不替换
切实的参照下面这链接:
http://stackoverflow.com/questions/433337/set-the-maximum-character-length-of-a-uitextfield

但是法只有会处理纯英文的输入,碰到中文输入法,就无可奈何判断了。
切实由我们下面分析

三. 搭建的点子

  1. 是因为Ambari是C/S架构,所以需要安排S到C的免密码ssh登录权限

  2. 构建yum本地源,这个好大大加快搭建的快及成功率

    reposync -r Updates-ambari-2.2.1.0 -p ./
    reposync -r HDP-2.4 -p ./
    reposync -r Updates-ambari-2.2.1.0 -p ./
    createrepo .

  3. 启动ambari-server

    yum install ambari-server
    amari-server setup
    ambari-server start
    默认的端口为 8080,用户名密码: admin/admin

  4. 在挨家挨户节点启动ambari-agent
    立刻有的操作可以了以web UI 下操作,十分便于。

添加机器节点



注意:需要上传之前免密码登录的私钥:id\_rsa

慎选要设置的服务

  • 首破尽量挑选要的组件,后面可以天天加
  • 瞩目:可以因实际情况改变部署之分布和配备,这个用以及硬件配置与事实上负荷情况折中

2.系统自带的汉语输入法

动系统中文输入法的下,会面世如下的场面,如图所示:

image

咱得以视于未曾按确认键之前,你输入的其余汉字只是以输入法的方显示出,在输入框中被灰色遮盖的片段才是显得你输入的字母,直到你按确认键之后,输入法者的字才会交替输入框中的被盖的假名。

题材就生出当输入框中被掩的有的(我们暂且称之为高亮部分,后面都是如此),因为用方面的计算输入框中字符数所占用的range,英文一个字母就是1,这个时统计是尚未问题的。

可是遇到上图所显示之状,这个法子对高亮部分的统计是发出问题的,我不清楚苹果内是如何算高亮部分所占用的range,完全无规律但论。不信大家可以自动打印一下range参数。假设我们限制最要命不得不输入10独字符,我们采取中文输入法的时节,大概在输入框中输入5顶6单字符(不是永恒不变换的,根据输入的字不同而不同)就未为我们继续输入了,因为高亮部分已经占据了10只字符了,虽然咱看来的高亮部分只出5,6个字符。

问题我们都查找出来了,下面我们看什么解决

@interface ViewController ()
@property(strong,nonatomic)UITextField *textField;
@property(assign,nonatomic)NSInteger maxCount;

@end

@implementation ViewController

- (void)viewDidLoad
{
    //监听UITextFieldTextDidChangeNotification通知,可以在UITextField发生变化的时候接收到通知
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(textFiledEditChanged) name:@"UITextFieldTextDidChangeNotification" object:nil];

    self.textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 200, 200, 44)];
    self.textField.backgroundColor = [UIColor redColor];
    [self.view addSubview:self.textField];
    self.maxCount = 10;

}

//实现监听方法
-(void)textFiledEditChanged{   
   NSString *toBeString = self.textField.text;  
   NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 键盘输入模式

   if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写       
      UITextRange *selectedRange = [self.textField markedTextRange];       //获取高亮部分的range

      //获取高亮部分的从range.start位置开始,向右偏移0所得的字符所在的位置。如果高亮部分不存在,那么就返回nil,反之就不是nil    
      UITextPosition *position = [self.textField positionFromPosition:selectedRange.start offset:0];       

      // 没有高亮选择的字,则对已输入的文字进行字数统计和限制       
      if (!position) {
           if (toBeString.length > self.maxCount) {
               self.textField.text = [toBeString substringToIndex:self.maxCount];
           }
       }       
       // 有高亮选择的字符串,则暂不对文字进行统计和限制
       else{                
        }   
      }   

      // 中文输入法以外的直接对其统计限制即可 
       else{
       if (toBeString.length > self.maxCount) {
           self.textField.text = [toBeString substringToIndex:self.maxCount];
       }
   }}

这上我们以输入中文输入法,发现并未问题了。

就是于咱们认为生功告成的时,手贱点了一下emoji表情,然后就是应运而生下面的题材了:

image

输入到第九只字之时候,我输入了一个emoji表情,然后就悲剧了,表情显得不完整

image

而是,既然问题应运而生了,我们还是来探哪化解吧

四. 线上之功用

装成功后的作用

其中:

  • Ambari Metrics
    负责实时采集端上系的体系统计信息,并保护各个服务之告警点条件
  • 每个服务都可经过以UI工具进行启动/停止/下线的操作
  • 可交到一个系统自带的分布式shell任务来测试集群运行的不易

su ambari-qa
cd /usr/hdp/2.4.0.0-169/hadoop-yarn/
yarn jar hadoop-yarn-applications-distributedshell.jar
hadoop-yarn-client.jar –jar
hadoop-yarn-applications-distributedshell.jar -container_memory 2
-master_vcores 3 -shell_args -a -shell_command ls

系中文输入法emoji表情截取错误

出现上面这个题目之案由是:emoji表情也是运用字符来表示的,不过貌似至少是2个字符表示,或者4单,6单来表示,不同之输入法无雷同。

咱地方的措施就是是粗暴的截取输入框中前10只字符,那么第九独汉字加上2独字符表示的神气便是11个字符了,这个时候emoji表情只被截取了前面一个字符,后面一个字符没有展示出,然后便悲剧了。

那么尽管解决办法就是,当我们输入emoji表情的当儿,需要做判定。

我们如果:

新的极致可怜字符数 = 输入框中的字符 + emoji表情字符。

那么:

一经,新的顶深字符数 <=
原始限制的极酷输入字符数,还是跟之前的处理方式类似

如若,新的极其可怜字符数 >
原始限制的极其可怜输入字符数,就安装:原始之限输入的极度深字符数 =
新的卓绝酷字符数。

问题即使化解了。

这边要运用NSString类中之有限单方法:

  • rangeOfComposedCharacterSequenceAtIndex
  • rangeOfComposedCharacterSequencesForRange

下来瞧这片独办法到底干嘛用之,来拘禁个小例子

NSString *str =  @"😄你好s🚣🏻🚜🔯🇮🇪s😄s";

    NSRange rangeIndex = [str rangeOfComposedCharacterSequenceAtIndex:5];
    NSString *string = [str substringWithRange:rangeIndex];

下是四种植情景:

image

image

image

image

可以看出这法子的企图就是是自rangeOfComposedCharacterSequenceAtIndex:<#(NSUInteger)#>的参数NSUInteger位置处于,向后计算一个整体字符串所占据的range。

当即不亏我们怀念只要之功效啊?

同理rangeOfComposedCharacterSequencesForRange:<#(NSRange)#>方就是是回来参数range范围外总体字符串所占据的新的range。

小生硬,看具体的例证:

image

可看看虽然咱的装的range是(0,6),刚好是字符‘s’之后的船舶的一个字符,这个时段该法返回来的range是(0,9),正好包括了所有船的字符。最后显示出的字符也是整体的均等才小船。

区区个措施说话得了了,我们来探望如何使即时点儿只方式来处理我们的问题,直接上代码

-(void)textFiledEditChanged{
    NSString *toBeString = self.textField.text;
    NSString *lang = [self.textField.textInputMode primaryLanguage];
    if ([lang isEqualToString:@"zh-Hans"])// 简体中文输入
    {
        //获取高亮部分
        UITextRange *selectedRange = [self.textField markedTextRange];
        UITextPosition *position = [self.textField positionFromPosition:selectedRange.start offset:0];

        // 没有高亮选择的字,则对已输入的文字进行字数统计和限制
        if (!position)
        {
            if (toBeString.length > self.maxCount) {
            self.textField.text = [toBeString substringToIndex:self.maxCount];
           }
       } 

       // 有高亮选择的字符串,则暂不对文字进行统计和限制
       else{                
        }   
    }


    // 中文输入法以外(英文和emoji)的直接对其统计限制即可
    else
    {
        if (toBeString.length > self.maxCount)
        {
            NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:self.maxCount];

            //如果是汉字,就直接截取到限制的最大字符数
            if (rangeIndex.length == 1)
            {
                self.textField.text = [toBeString substringToIndex:self.maxCount];
            }

            //如果不是汉字,那就是emoji表情了,就截取到包括完整emoji表情后的range范围的字符
            else
            {
                NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, self.maxCount)];
                self.textField.text = [toBeString substringWithRange:rangeRange];
            }
        }
    }

}

还来运行下,发现简直无微不至,按捺住内心的多少感动。然后试了生第三正输入法搜狗和百度,输入到emoji表情的时,又冒出emoji表情截取错误。。。

image

自家赵日天不服啊,继续解决bug

五. 常见问题

  1. nfs3 gateway挂载,以及input/output error和进度问题
    Ambari会自动启动nfs3服务,但是挂载需要好操作

    mount -t nfs -o vers=3,proto=tcp,nolock $server_ip:/ /opt/hdfs/

    并且,需要在web端修改参数

避免input/output error 配置参数

挂载的默认rtmax和wrmax是1MB,如果有大文件,调高这个参数会有速度上的提升

其三方中文输入法emoji表情截取错误

实则想了下,很好解决,复制黏贴代码就得了。我们以运用中文输入法的下啊举行一下断定嘛。

代码如下:

-(void)textFiledEditChanged{
    NSString *toBeString = self.textField.text;
    NSString *lang = [self.textField.textInputMode primaryLanguage];
    if ([lang isEqualToString:@"zh-Hans"])// 简体中文输入
    {
        //获取高亮部分
        UITextRange *selectedRange = [self.textField markedTextRange];
        UITextPosition *position = [self.textField positionFromPosition:selectedRange.start offset:0];

        // 没有高亮选择的字,则对已输入的文字进行字数统计和限制
        if (!position)
        {
            if (toBeString.length > self.maxCount)
            {
            //判断第三方中文输入法的emoji表情
                NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:self.maxCount];
                if (rangeIndex.length == 1)
                {
                    self.textField.text = [toBeString substringToIndex:self.maxCount];
                }
                else
                {
                    NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, self.maxCount)];
                    self.textField.text = [toBeString substringWithRange:rangeRange];
                }
            }
        }
    }

    // 中文输入法以外(英文和emoji)的直接对其统计限制即可
    else
    {
        if (toBeString.length > self.maxCount)
        {
            NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:self.maxCount];
            if (rangeIndex.length == 1)
            {
                self.textField.text = [toBeString substringToIndex:self.maxCount];
            }
            else
            {
                NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, self.maxCount)];
                self.textField.text = [toBeString substringWithRange:rangeRange];
            }
        }
    }

}

运行下

image

PS:
地方的措施,还非可知针对付颜文字,火星文之类的,还是会现出截取错误~

重多技术文章欢迎大家看我之个人博客:Ximu&Moliang’s
Blog

六. 参考

【Ambari——大数量平台的搭建利器】
【Ambari——大数额平台的搭建利器的前进阶篇】