2017-05-18 11 views
2

저는 현재 특정 정부 지침 (의료 및 웰빙 문구)으로 인해 앱에서 언어를 변경해야하는 클라이언트를 돕고 있습니다. 그들의 애플 리케이션은 거대하고 모든 문자열은 코드에 포함되어 있습니다 (stringWithFormat/hardcoded), 그것의 아무 것도 외부 테이블에 있습니다. 이것은 거대한 수작업 일 것입니다.NSString 하위 클래스 또는 래퍼 클래스 또는 범주

미래에 결정되지 않은 시점에서 고객은 현재 문언으로 돌아 가기위한 승인을받을 것으로 생각하고 문자열을 다시 전환하려고합니다. 변화의 대부분은 말 그대로 문제가되는 단어 하나를 문제가 적은 단어로 바꿔 놓을 것입니다.

필자는 부울 스위치를 기반으로 런타임에 문자열을 변경할 수 있으면 관련 수동 작업을 제거하고 필요시 언어를 다시 전환 할 수 있다고 생각했습니다.

첫 번째 시도 : 내가 먼저 신속하게 문제가있는 단어를 대체 할 stringWithFormat을 재정의 할 범주를 구분

+ (instancetype)stringWithFormat:(NSString *)format, ... 
{ 
    va_list args; 
    va_start(args,format); 
    //todo check flag if we're changing the language 
    //todo replace problematic word from 'format' 
    NSString *result = [NSString stringWithFormat:format,args]; 

    return result; 
} 

. stringWithFormat의 원래 구현을 잃어버린다는 사실을 잊어 버렸습니다. 이로 인해 끝없는 재귀가 발생했습니다.

다음 시도 (서브 클래스) :

나는있는 NSString를 서브 클래 싱하기위한 시도를 시작했지만 내 솔루션은 클래스 클러스터를 서브 클래스 인 경우 클래스 클러스터를 서브 클래 싱하기 때문에 나는 내 문제를 이해하지 않았다고 말하는 유래의 골대에 맞았습니다 거의 끝나지 않았다.

마지막 옵션 (래퍼) :

내 마지막 시도가 래퍼 클래스하지만 패배 수동으로 응용 프로그램의 각 문자열을 찾는 것을 피하기 위해했던 원래 목적의 종류를 작성하는 것입니다.

저는이 문제에 대해 더 이상 어떻게 접근해야하는지 잘 모르겠습니다. 핵심 클래스 중 하나에 기능을 추가/재정의해야 할 경우 어떻게해야합니까?

+1

관련 : [있는 NSArray 또는 다른 클래스 클러스터 원숭이 패치 방법은 없나요 또는 스위 즐링 (swizzle)?이 솔루션은 그러나 일 대부분의 경우 (http://stackoverflow.com/q/11751473) –

답변

1

훨씬 더 딱 맞는 것처럼 보이는 훨씬 간단한 솔루션이 있습니다.

displayString *NSString = NSLocalizedString(@"displayString", nil); 
cancelButtonTitle *NSString = NSLocalizedString(@"cancelButtonTitle", nil); 

가 다음 앱에서 Localizable.strings 파일을 생성하고 표시해야 실제 값을 정의 : 대신 실제 문자열의 키, NSLocalizedString 사용
"displayString" = "The string to display in English" 
"cancelButtonTitle" = "Cancel" 

당신은 지역화를 넣어. 문자열 파일을 앱 번들에 넣고 앱이이를 사용하여 런타임에 문자열 바꾸기를 수행합니다.

다른 언어에 대해 다른 버전의 Localizable.strings을 정의 할 수도 있습니다. 예를 들어 사용자가 언어를 스페인어로 설정 한 경우 NSLocalizedString()을 호출하면 스페인어 버전이 제공됩니다.

(앞서 언급했듯이 NSString은 클래스 클러스터입니다. 즉, 다양한 개인 서브 클래스에 대한 공용 인터페이스라는 것을 의미합니다. NSString을 작성할 때 어떤 개인 서브 클래스를 얻을 수 있는지, 그리고 서브 클래 싱을 시도하는 것은 바람직하지 않습니다.)

1

하드 코드 된 문자열의 경우 문자열 변환기 클래스에 할당하여 수동으로 수정할 수는 없습니다.그래서 사람들을 위해 :

yourmom.text = @"Hi Mom"; 
yourdad.text = [NSString stringWithFormat:@"%@ and Dad!",yourmom.text]; 

당신은 스토리 보드 또는 xibs 문자열에 관해서는, 당신이있는 viewDidLoad에서 반복 루프에 의해 변경할 수 있습니다

yourmom.text = [StringConverter string:@"Hi Mom"]; 
yourdad.text = [StringConverter string:@"%@ and Dad!" placeHolder:yourmom.text]; 

처럼 뭔가 과제의 이러한 종류를 변경해야합니다. 행운을 빕니다.

1

처음 시도한 아이디어에는 아무런 문제가 없으며 구현시 약간의 실수가 있습니다. 변경 :

NSString *result = [NSString stringWithFormat:format,args]; 

에 : stringWithFormat:의 확장이며, 차단이 작동

NSString *result = [NSString alloc] initWithFormat:format arguments:args]; 

. 클래스 클러스터에 대한

생각이 특정 상황에서 붉은 청어, 클래스 메소드에 대한 구현을 제공해야합니다 클러스터 (NSString) (+stringWithFormat:)에 대한 전면 클래스, 그래서 당신이 그들을 차단하는 간단한 범주를 사용할 수 있습니다. 그러나

+stringWithFormat:주의 차단 한. 간단한 테스트는 프레임 워크가 많이 사용했음을 보여 주며, 프레임 워크에 의해 많이 사용되었으므로 파손하지 않으려합니다. 첫 번째 간단한 테스트는 "d"를 "c"로 변경하여 "창"을 "wincow"로 변경하고, Xcode의 기본 응용 프로그램에서 "창"속성을 바인드하는 바인딩 설정이 끊어졌습니다. ...

건강 관련 단어를 변경하면 전체 문자열이 더 좋을 것입니다.

더 나은 방법은 코드에있는 모든 리터럴 문자열을 일치 시키려면 RE를 쓰고 변환을 위해 작성하는 일부 함수 (메서드가 아닌)는 function(string)으로 대체하는 것입니다.

HTH

+0

나는 걸림돌을 때렸다. ** 알 수없는 예외 'NSInvalidArgumentException'으로 인해 앱을 종료합니다. 이유 : 'appendString을 사용하여 변경 불가능한 개체를 변경하려고 시도했습니다.' 그래서 변경했습니다. 오류입니다. crashlytics/fabric과 관련이 있습니다. 그래서 네 말이 맞아 ... 프레임 워크를 깨뜨리는거야. : D – Atomhax

+0

이 stringWithFormat도 NSMutableString과 함께 사용되며이 재정의 된 함수에서 NSString 만 반환하고 있습니까? 따라서 Mutable String을 고려하여 구현을 변경해야합니다. – Atomhax

+1

'NSMutableString'에도 범주를 추가하려고 했습니까? 프레임 워크를 깨뜨리는 것에 대한 우려는 인터셉트 * 그 자체가 아니라 메소드의 동작 *을 어떻게 수정할 수 있는지에 있습니다. 나는이 방법을 바꾸는 것이 최선의 접근법이라고 말하지는 않겠지 만, 근원 변화를 최소화하는 이점이 있습니다. – CRD