Requirements: Use resource files in the SDK, such as xib, image, string internationalization, etc.
Prerequisites for reading:
- Know how to create an SDK
- Know how to import and use an SDK in a project
GitHub address (with code)How do I use resource files in the SDK
Letter Address:How do I use resource files in the SDK
Blog Address:How do I use resource files in the SDK
Address of nuggets:How do I use resource files in the SDK
The principle of
Using XIBs, images or other resource files in the SDK is different from using them directly in a project, because we have to be clear that only.h,.m,.mm,.swift files can be imported directly into the SDK, like images, xib files, Resource files such as internationalized.string files cannot be found directly through the Framework loading path, We must add the resource files (nib, image,.string…) to Build Phases’ Copy Bundle Resources. Therefore, we had better create a new Bundle file in the SDK to store all the resource files, and then Copy the Bundle Resources in the main project to add this Bundle file to load all the resource files in the SDK.
Create a Bundle
To store all resource files in SDK in a unified manner
Note: We need to manually or script the resource files to be automatically copied into the Bundle after each build for them to take effect in the main project.
All the resource files we use for the SDK project from now on should be placed in the Bundle.
Scene classification
Use Xib files
1. Build SDK project
If the project contains XIB files, niB files are automatically generated in the Framework each time the project is compiled, as shown in the figure below
2. Put the newly compiled Framework into the project
- First, copy the compiled framework into our project directory.
- There are two ways to use Nib files
- Import the Nib file directly into the main project resource file
- (Recommended) Put the compiled Nib files in the Framework into the Bundle, and then import the Bundle into the resource file of the project. The advantage is that all resource files in a Framework can be managed in a unified manner
If only NIB is used, the following figure is shown; otherwise, the bundle can be imported into the project in the same way
3. Use the XIB file in the SDK
- Use niB files directly from the framework
NSString *path = [[NSBundle mainBundle] pathForResource:@"XDXTestFramework" ofType:@"framework"];
TestJumpVC *vc = [[TestJumpVC alloc] initWithNibName:@"TestJumpVC" bundle:[NSBundle bundleWithPath:path]];
[self presentViewController:vc animated:YES completion:nil];
Copy the code
- (Recommended) Use niB files from bundles in the Framework.
Because we already put the bundle into the project’s copy Bundle Resources in step 2, we use [NSBundle mainBundle] in the following code
NSString *path = [[NSBundle mainBundle] pathForResource:@"XDXAllResources" ofType:@"bundle"];
TestJumpVC *vc = [[TestJumpVC alloc] initWithNibName:@"TestJumpVC" bundle:[NSBundle bundleWithPath:[path stringByAppendingString:@"/xibs"]]];
[self presentViewController:vc animated:YES completion:nil];
Copy the code
If it is not in step 2 import nib files project program will crash, and prompt “Terminating app due to uncaught exception ‘NSInternalInconsistencyException, reason: ‘Could not load NIB in bundle: ‘NSBundle </var/containers/Bundle/Application/D46C1A83-E6F4-4DB2-8F02-EC0ED05C6C99/XDXSDKResourceFileDemo.app> (loaded)’ With the name ‘TestJumpVC’ ‘ ‘
Two. Use pictures
1. Copy the image to the bundle created in the Framework
2. Using the image, load the path of the image in the bundle (Note: it must be the same as the real path, please refer to Demo).
// Test image
NSString *path = [[[NSBundle mainBundle] pathForResource:@"XDXAllResources" ofType:@"bundle"] stringByAppendingString:@"/images/1.png"];
self.testImage.image = [UIImage imageWithContentsOfFile:path];
Copy the code
Iii. Use international language adaptation (Chinese and English adaptation)
1. Create. String files to support Both English and Chinese
2. Localize strings files to support multiple languages
3. Configure the project to support multiple voice calls
4. Add corresponding characters to the multi-language file
5. Create the NSBundle class to provide class methods to support the use of multiple languages in the SDK
The principle is the same as above, that is, find the corresponding Sting file in English and Chinese in Budle, And then use – (NSString *)localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *) *)tableName NS_FORMAT_ARGUMENT(1); Method to retrieve strings from the bundle for the corresponding language.
The code involves the APP to manually select the Chinese and English mode, but we mainly implement according to the language environment currently set by the system, so we ignore the situation of setting the language artificially
// Note: Be consistent with you create bundle's name.#define XDXRouterResBundle @"XDXAllResources"
@implementation NSBundle (XDXLocalizable)
+ (instancetype)XDX_localizableBundleWithBundleName:(NSString *)bundleName {
static NSBundle *localizableBundle = nil;
if (localizableBundle == nil) {
if(! bundleName) { bundleName = XDXRouterResBundle; } NSString *bundleType = nil;if(bundleName && ! [bundleName hasSuffix:@"bundle"]) {
bundleType = @"bundle";
}
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:bundleName ofType:bundleType];
localizableBundle = [NSBundle bundleWithPath:bundlePath];
}
return localizableBundle;
}
+ (NSString *)XDX_localizedStringForKey:(NSString *)key {
return [self XDX_localizedStringForKey:key value:nil];
}
+ (NSString *)XDX_localizedStringForKey:(NSString *)key value:(NSString *)value{
NSBundle *bundle = nil;
//NSString *language = [self getLanguageFromSystem];
//NSString *language = [self getLanguageFromPlist];
NSString * language = [self getLanguageFromDevelopersSetup];
if(! language) { language = [self getLanguageFromSystem]; NSLog(@"Current language is %@",language); } / / from FrameworkTestBundle bundle finds the resource nsstrings * bundlePath = [[NSBundle XDX_localizableBundleWithBundleName: nil] pathForResource:language ofType:@"lproj"];
bundle = [NSBundle bundleWithPath:bundlePath];
value = [bundle localizedStringForKey:key value:value table:nil];
return[[NSBundle mainBundle] localizedStringForKey:key value:value table:nil]; } // This language is set by reading the current system language + (NSString *)getLanguageFromSystem{NSString *language = [NSLocale preferredLanguages].firstObject;if ([language hasPrefix:@"en"]) {
language = @"en";
} else if ([language hasPrefix:@"zh"]) {
if ([language rangeOfString:@"Hans"].location ! = NSNotFound) { language = @"zh-Hans"; // Simplified Chinese}else {
language = @"zh-Hant"; // Chinese}}else {
language = @"en";
}
returnlanguage; + (NSString *)getLanguageFromPlist{NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"SDKInternationalizationDemoPlist.plist" ofType:nil];
if(! bundlePath) {return nil;
}
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:bundlePath];
if (dict) {
NSInteger languageNum = [[dict valueForKey:@"language"] integerValue];
switch (languageNum) {
case 1:
return @"en"; // Language is English: enbreak;
case 2:
return @"zh-Hans"; // The language is zh-hansbreak;
case 3:
return @"zh-Hant"; // The language is zh-hanzbreak;
default:
return @"en";
break; }}return @"en"; } // This is the setup language called manually by the developer, From NSUserDefaults to read kDSADLanguageStyle inside this field is a kind of language which + (nsstrings *) getLanguageFromDevelopersSetup {NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSInteger languageStyle = [[userDefaults valueForKey:@"TODO"] integerValue];
if(! languageStyle) {return nil;
}
switch (languageStyle) {
case 1:
return @"en";
break;
case 2:
return @"zh-Hans";
break;
case 3:
return @"zh-Hant";
break;
default:
return @"en";
break;
}
}
@end
Copy the code
6. Use multilingual strings in your code
self.testLabel.text = [NSBundle XDX_localizedStringForKey:@"Test"];
Copy the code
Bonus: Add scripts to copy resource files into bundles each time the Framework is compiled
why
Whenever a resource file changes, such as adding or removing images, adding new fields to the strings file, etc., we need to manually place the new file in the Bundle’s folder. If we want to use the script to automatically place all the resource files, we can use Xcode’s feature.
operation
-
First, create a new script in your project
-
Second, copy all the resource files of our project to the corresponding directory in the bundle in the script. (Note: the file path must be correct. If you encounter niB files in the Framework, the project location is not used on the PC, so you need to query and modify it.)
-
Finally, after we Build the project, all the resource files are updated to the latest