Swift의 String.count와 Java의 String.length()는 다르다.

작성일 :

개요


"👩‍👩‍👦" 이모지는 3명의 사람(여성 2명, 소년 1명)으로 이루어진 가족을 나타내는 이모지입니다. 이모지를 Swift와 Java에서 문자열로 선언하고 각각의 count와 length를 계산해보겠습니다.

Swift:

swift
let family: String = "👩‍👩‍👦"
print(family.count) // 1

Java:

java
String family = "👩‍👩‍👦";
System.out.println(family.length()); // 8

위 코드에서 볼 수 있듯이, Swift에서는 이모지가 1개의 문자로 인식되어 count가 1이 되지만, Java에서는 8개의 코드 유닛으로 이루어진 문자열로 인식되어 length가 8이 됩니다.

따라서, Swift와 Java에서 이모지를 문자열로 다룰 때에는 count와 length의 결과값이 다르게 나올 수 있으므로 주의가 필요합니다.

이는 일반적인 상황에서 문제가 되지 않지만, 사용자가 콘텐츠를 많이 올리는 서비스(ex SNS)에서 사용자의 콘텐츠의 글자 제한을 주는 경우 안드로이드와 iOS 각각 플렛폼에서 validation하는 기준이 다르기 때문에 사소한 문제가 발생할 수 있습니다.

Java와 Swift의 문자열 count가 다른 이유


이유는 "👩‍👩‍👦" 이 이모지는 여성 2명과 남성 1명으로 이루어진 조합 이모지이기 때문입니다. 이 조합 이모지는 여성 2명을 나타내는 "👩‍👩"과 남성 1명을 나타내는 "👦" 세 개의 이모지를 결합한 것입니다.

Swift에서는 문자열의 count를 유니코드 그래프 클러스터링 (Unicode grapheme clustering) 단위로 계산합니다. 유니코드 그래프 클러스터링은 사용자가 인식하는 문자 단위로 문자열을 나누는 방법으로, 이모지의 경우 결합된 이모지 조합도 하나의 문자로 계산합니다. 따라서 "👩‍👩‍👦" 이 이모지의 count는 1이 됩니다.

반면에 Java에서는 문자열의 length를 유니코드 코드 유닛 (Unicode code units) 단위로 계산합니다. 유니코드 코드 유닛은 각각의 코드 포인트를 나타내는 16비트 코드 유닛으로 문자열의 길이를 계산하는 방법입니다. 따라서 "👩‍👩‍👦" 이 이모지의 length는 8이 됩니다.

Java와 Swift의 문자열 count를 맞추는 방법


바이트 비교

바이트 비교 방식은 유용할 수 있습니다. 하지만 문자열 내에 이모지 또는 멀티바이트 문자가 있는 경우 문자열의 길이를 정확하게 측정하기 어려울 수 있습니다. 예를 들어, UTF-8 인코딩을 사용하는 문자열에서 이모지는 4바이트로 표현되므로, 문자열을 바이트로 변환하고 그 길이를 측정하면 이모지가 여러 개 포함된 문자열의 길이가 정확하게 나오지 않을 수 있습니다. 따라서 이 방식은 정확성이 보장되지 않을 수 있으며, 주의해서 사용해야 합니다.

각 플랫폼의 자바스크립트 엔진으로 count를 재계산하는 방식

각 플랫폼의 자바스크립트 엔진으로 문자열을 처리하는 것은 가능합니다. 하지만 이 방법은 문자열의 크기와 복잡도에 따라서 처리 속도가 느리고, 플랫폼 간 결과가 다를 수 있기 때문에 권장되는 방법은 아닙니다.

또한, 이 방법도 이모지와 같은 복합 문자의 처리에 대한 정확도 문제가 있을 수 있습니다. 따라서, 문자열 처리에 대한 정확성을 보장하려면 각 플랫폼에서 제공하는 문자열 처리 함수를 사용하는 것이 좋습니다.

결론


이 글을 작성하며 여러가지 방식을 찾아 보았으나, 합리적으로 두 플랫폼의 String Count를 맞추는 방법을 찾지 못했습니다. 따라서 각 플랫폼 글자 counting 방식이 다를 수 있다는 것을 인정하고, DB type을 넉넉하게 설정하고, 글자 제한에 대해서 유연하게 대처해야 합니다. 혹시 좋은 방법이 있다면 댓글로 알려주세요. 감사합니다.