2011-11-24 5 views
13

デバイス名からというユーザ名をという名前で抽出する機能を作った。デバイスからユーザーの名前を取得すると便利ですか?

は、最初にアプリを起動するときにユーザがをプレイするためにまっすぐに進むことを可能にする設定手順をスキップすることです。

これは、ユーザーの名前を保持するためにデバイス名を信頼することはできないので、これは最適な方法です。です。問題は次のとおりです。これを行うにはどうすればよいでしょうか?デバイスのデフォルト名は( "サンナのiPod")変更されていない場合は、以下の

My機能は、英語で...

  • ... ...
    • を右の名前を取得します
    • ...フランス語などでも同様です(「iPod de Sanna」)
    • ...スウェーデン語などで「Sannas iPod」という名前がSで終わらない場合(「Johannes iPod」=>「Johanne名前自体がSで終わるので、「Johannes」を正しく返すべきである)

    ユーザーがデバイスの名前を既定のフォーム以外に変更した場合、明らかに名前が正しく表示されません。

    - (NSString *) extractPlayerNameFromDeviceName: (NSString *) deviceName { 
    
        // get words in device name 
        NSArray *words = [deviceName componentsSeparatedByString:@" "]; 
        NSMutableArray *substrings = [[NSMutableArray alloc] init]; 
        for (NSString *word in words) { 
         NSArray *subwords = [word componentsSeparatedByString:@"'"]; 
         [substrings addObjectsFromArray:subwords]; 
        } 
    
        // find the name part of the device name 
        NSString *playerName = [NSString stringWithString: @""]; 
        for (NSString *word in substrings) { 
         if ([word compare:@"iPhone"] != 0 
          && [word compare:@"iPod"] != 0 
          && [word compare:@"iPad"] != 0 
          && [word length] > 2) { 
          playerName = word; 
         } 
        } 
    
        // remove genitive 
        unichar lastChar = [playerName characterAtIndex:[playerName length] - 1]; 
        if (lastChar == 's') { 
         playerName = [playerName substringToIndex:[playerName length] - 1]; 
        } 
        lastChar = [playerName characterAtIndex:[playerName length] - 1]; 
        if (lastChar == '\'') { 
         playerName = [playerName substringToIndex:[playerName length] - 1]; 
        } 
        return playerName; 
    } 
    

    私のアプリでユーザー名を提案するために使用します。このようにして、ほとんどのユーザーはユーザー名の書き込みを気にする必要はありません。

    私のアプリはiTunesやFacebookのような他のサービスには接続されていませんが、すべてのユーザーはユーザー名が必要です。だから私はどのように名前を取得するのですか?

    +0

    サービスですアプリケーションの外部で使用できますか?例えばPC上ではどういう意味ですか? –

    +0

    '[[UIDevice currentDevice] name]'はあなたが望むものを返しますか? –

    +0

    @HenriNormak:いいえ、これは基本的にどこにも接続していないiPhone/iPod用のアプリです。 – JOG

    答えて

    1

    iPodとiPhoneだけの場合は、なぜユーザー名を使用するのですか? Webサービス用のデバイスを特定する必要がある場合は、各デバイスに固有の他の値(UDIDなど)があります。他のオプションは、ユーザーが自分自身を表すアドレス帳から連絡先を選択し、そのデータを使用させることです。

    +1

    1: "Henri"や "Guest player"のように、プレイしているGUIで表示するために名前を使用します。 2:演奏結果は、アプリケーション外の他のプレイヤーとの比較のためにエクスポートできます。 – JOG

    +0

    次に、2番目の提案を使用して、ABAddressBookを使用して連絡先カードをリストから選択させるようにしてください。リストからタップした最初の起動は、正直言ってユーザーとあなたの両方にとって簡単です。 –

    +0

    それはうまくいく!しかし、アイデアは、ユーザーが最初にアプリを起動するとすぐにプレイできるように設定手順をスキップすることです。それがすべて可能ならば。このテキストを質問に追加します。 – JOG

    4

    ここでは、すべての名前を取得する代わりの方法です。また、 "de"や "s"を使用する言語の最後には 's'は削除されません。また、各名前の最初の文字を大文字にします。

    メソッドの実装:

    - (NSArray*) newNamesFromDeviceName: (NSString *) deviceName 
    { 
        NSCharacterSet* characterSet = [NSCharacterSet characterSetWithCharactersInString:@" '’\\"]; 
        NSArray* words = [deviceName componentsSeparatedByCharactersInSet:characterSet]; 
        NSMutableArray* names = [[NSMutableArray alloc] init]; 
    
        bool foundShortWord = false; 
        for (NSString *word in words) 
        { 
         if ([word length] <= 2) 
          foundShortWord = true; 
         if ([word compare:@"iPhone"] != 0 && [word compare:@"iPod"] != 0 && [word compare:@"iPad"] != 0 && [word length] > 2) 
         { 
          word = [word stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[word substringToIndex:1] uppercaseString]]; 
          [names addObject:word]; 
         } 
        } 
        if (!foundShortWord && [names count] > 1) 
        { 
         int lastNameIndex = [names count] - 1; 
         NSString* name = [names objectAtIndex:lastNameIndex]; 
         unichar lastChar = [name characterAtIndex:[name length] - 1]; 
         if (lastChar == 's') 
         { 
          [names replaceObjectAtIndex:lastNameIndex withObject:[name substringToIndex:[name length] - 1]]; 
         } 
        } 
        return names; 
    } 
    

    使用法:

    // Add default values for first name and last name 
    NSString* deviceName = [[UIDevice currentDevice] name]; 
    NSArray* names = [self newNamesFromDeviceName:deviceName]; 
    // This example sets the first and second names as the text property for some text boxes. 
    [self.txtFirstName setText:[names objectAtIndex:0]]; 
    [self.txtLastName setText:[names objectAtIndex:1]]; 
    [names release]; 
    
    +0

    これは "Sannas iPod"では正しく動作しません。 – JOG

    +0

    私はこのメソッドがうまく動作し、ただ1つの名前を返すと信じています。 lastNameが存在するかどうかをチェックしないので、私の例の "Usage"部分が爆発するでしょう。 –

    +0

    私はこの文字列をNSCharacterSetに使用しました:@ "" '\\ "。これはAppleがデバイス名で使用するカーブしたUTF8アポストロフィを含みます。 –

    0
    NSString *dname=[[UIDevice currentDevice] name]; 
    dname=[dname componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"'的"]][0]; 
    
    8

    私はリッキーHelegessonの答えの改善を提供したいと思います。それには以下の特徴があります。

    • 正規表現を使用しているため効率は低下しますが、それは一度だけ呼び出す必要があります。
    • "iPhone"と同様に、 "iPhone"だけでなく "iPhone"も含めて使いました。
    • "iPad"、 "iPhone"の直前に "しかし、文字列の最後にのみ。
    • "iPad Simulator"のように、最初の単語であるときに "iPad"などを削除します。
    • 各単語の最初の文字を大文字にします。
    • 大文字と小文字は区別されません。
    • 依存関係がないため、関数です。

    ここではコードです:

    NSArray * nameFromDeviceName(NSString * deviceName) 
    { 
        NSError * error; 
        static NSString * expression = (@"^(?:iPhone|phone|iPad|iPod)\\s+(?:de\\s+)?|" 
                "(\\S+?)(?:['’]?s)?(?:\\s+(?:iPhone|phone|iPad|iPod))?$|" 
                "(\\S+?)(?:['’]?的)?(?:\\s*(?:iPhone|phone|iPad|iPod))?$|" 
                "(\\S+)\\s+"); 
        static NSRange RangeNotFound = (NSRange){.location=NSNotFound, .length=0}; 
        NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:expression 
                          options:(NSRegularExpressionCaseInsensitive) 
                           error:&error]; 
        NSMutableArray * name = [NSMutableArray new]; 
        for (NSTextCheckingResult * result in [regex matchesInString:deviceName 
                     options:0 
                      range:NSMakeRange(0, deviceName.length)]) { 
         for (int i = 1; i < result.numberOfRanges; i++) { 
          if (! NSEqualRanges([result rangeAtIndex:i], RangeNotFound)) { 
           [name addObject:[deviceName substringWithRange:[result rangeAtIndex:i]].capitalizedString]; 
          } 
         } 
        } 
        return name; 
    } 
    

    リターン名前のためにこれを使用するには、

    NSString* name = [nameFromDeviceName(UIDevice.currentDevice.name) componentsJoinedByString:@" "]; 
    

    これはやや複雑なので説明します。

    1. 正規表現には3つの部分があります。
      1. 文字列の先頭に「iPhone」、「iPod」、「iPad」または「phone」とオプションの単語「de」は表示されません。
      2. 文字列の最後に、オプションの「 's」(返されない)と「iPad」、「iPhone」、「iPod」または「phone」どちらも返されません)。
      3. この一致は前と同じですが、中国語のデバイス名でも有効です。 (Travis Wormの提出から適応されました。間違っている場合は教えてください)
      4. 前のルールと一致しない単語に一致して返されます。
    2. すべての一致を繰り返し、それらを大文字にして配列に追加します。
    3. 配列を返します。

    「iPad」の前にアポストロフィを付けずに「s」で終わる名前は、「s」がその一部であるかどうかを判断する簡単な方法ではないため、変更しないでください。名前の名前または複数形。

    お楽しみください!

    私はここに要旨を作成しました...

    をスウィフトに元Owen Godfrey答えを変換し、User's iPhone 6SまたはiPhone 5 de Userのような複数のパターンをサポートするために、regExprのを更新しました

    3

    https://gist.github.com/iGranDav/8a507eb9314391338507

    extension UIDevice { 
    
    func username() -> String { 
    
        let deviceName = self.name 
        let expression = "^(?:iPhone|phone|iPad|iPod)\\s+(?:de\\s+)?(?:[1-9]?S?\\s+)?|(\\S+?)(?:['']?s)?(?:\\s+(?:iPhone|phone|iPad|iPod)\\s+(?:[1-9]?S?\\s+)?)?$|(\\S+?)(?:['']?的)?(?:\\s*(?:iPhone|phone|iPad|iPod))?$|(\\S+)\\s+" 
    
        var username = deviceName 
    
        do { 
         let regex = try NSRegularExpression(pattern: expression, options: .CaseInsensitive) 
         let matches = regex.matchesInString(deviceName as String, 
                  options: NSMatchingOptions.init(rawValue: 0), 
                  range: NSMakeRange(0, deviceName.characters.count)) 
         let rangeNotFound = NSMakeRange(NSNotFound, 0) 
    
         var nameParts = [String]() 
         for result in matches { 
          for i in 1..<result.numberOfRanges { 
           if !NSEqualRanges(result.rangeAtIndex(i), rangeNotFound) { 
            nameParts.append((deviceName as NSString).substringWithRange(result.rangeAtIndex(i)).capitalizedString) 
           } 
          } 
         } 
    
         if nameParts.count > 0 { 
          username = nameParts.joinWithSeparator(" ") 
         } 
        } 
        catch { NSLog("[Error] While searching for username from device name") } 
    
        return username 
    } 
    } 
    
    関連する問題