iOS App Thinning – App Thinning

Estimated read time 4 min read

1 App Thinning

App thinning is a technique for optimizing mobile applications to reduce their installation package size and improve performance. It is a method developed by Apple for iOS applications in order to make the application more suitable for various different types of iOS devices.

App Thinning mainly includes technologies:

  • Slicing (iOS, tvOS)
  • Bitcode
  • On-Demand Resources (iOS, tvOS)

1.1 Slicing

Slice Apps are supported on iOS 9.0 and higher devices.

Slicing is the process of creating and delivering app bundle variations for different target devices and operating system versions. When a user installs an app, the system downloads and installs variations of the user’s device and operating system version.

Xcode simulates slicing during development. When you build and run the app on a device or simulator, Xcode slices the app. When you create an archive, Xcode includes the full version of the app, but allows you to export variants from the archive.

work process:

  1. In Xcode, specify the target device and use Asset Catalogs to provide images in multiple resolutions. Only by using Asset Catalogs can Slicing be applied to resource files correctly.
  2. Compile and run on the simulator or real device. Xcode automatically builds “variant apps” for the running device, reducing compilation time and supporting local testing of different variants.
  3. Archieve, export a variant locally for the target device. Multiple “variant apps” can be exported locally to test and fix configuration errors.
  4. Upload to App Store Connect. The App Store creates “Variant Apps” based on the uploaded .ipa archive file. The number of “Variant Apps” depends on the architecture and resources configured in the Xcode project.
  5. Upload to publish a preview version in App Store Connect for testing. Download the preview version through TestFlight, and TestFlight downloads the appropriate “variant app” for the target device.
  6. Publish the app. App Store Download the appropriate “variant App” for the user’s device

1.2 Bitcode 

Bitcode is an intermediate representation of a compiled program. Apps uploaded to App Store Connect that contain bitcode will be recompiled and linked on the App Store.

In the future, if Apple launches a new CPU architecture or LLVM launches a series of optimizations, the Apple Store will automatically re-optimize the application binary file without having to submit a new version to the App Store again.

Enable steps: Build Settings -> Enable Bitcode -> YES

Notes on enabling Bitcode:

  • The static libraries, dynamic libraries, and third-party libraries managed by Cocoapods that the App depends on all need to enable Bitcode.
  • The final generated executable file is automatically generated by Apple, and new symbol table files (dSYMs) are generated, which require symbol remapping to ensure correct parsing of crash logs and debugging information.

1.3 On-Demand Resources

On-Demand Resources (ODR)

The App Store hosts some of its resources on Apple servers and manages downloads for you. The App Store also slices on-demand resources to further optimize App variants.

Precautions:

  • When a user enters a certain business, on-demand resources are downloaded in the background as needed.
  • When on-demand resources are no longer needed and disk space is low, the operating system clears them.

Load configuration  &  request resources on demand

Use the on-demand loading feature:

1. Enable steps: Build Settings -> Enable On-Demand Resources -> YES

2. Select the Resources Tag -> Download Only On Demand -> add “+” and name the resource tag

Resources Tag Introduction:

  • Initial install tags: Initial installation tags. Resources will be downloaded as the App is downloaded from the App Store, which will affect the size of the ipa
  • Prefetch tag order: Prefetch tag order. After the App is downloaded, the corresponding resources will start to be downloaded. Such resources will not affect the size of the ipa. Suitable for game scenarios
  • Dowloaded only on demand: Downloaded only on demand. Resources will actively trigger downloads when necessary, and developers control the download timing.

3. Download on-demand resources

- (void)onDemandDownload {

// 创建资源请求,指定需要的资源标签
NSArray<NSString *> *tags = @[ @"ImageAssets" ];
NSBundleResourceRequest *request = [[NSBundleResourceRequest alloc] initWithTags:tags];

// 开始访问资源
[request beginAccessingResourcesWithCompletionHandler:^(NSError * _Nullable error) {
if (error) {
// 处理异常情况
[self handleResourceRequestError:error];
return;
}

// 资源下载完成,可以开始使用资源
dispatch_async(dispatch_get_main_queue(), ^{
// 在主线程中更新 UI 或执行其他操作
// 加载资源,例如显示图像
NSBundle *bundle = request.bundle;
UIImage *image = [UIImage imageNamed:@"exampleImage" inBundle:bundle compatibleWithTraitCollection:nil];
self.imageView.image = image;

// 使用完成后释放资源请求
[request endAccessingResources];
});
}];
}

- (void)handleResourceRequestError:(NSError *)error {
if (error.code == NSBundleOnDemandResourceOutOfSpaceError) {
// 处理空间不足错误
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Error"
message:@"Insufficient space on device. Please clear some space and try again."
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
} else if (error.code == NSBundleOnDemandResourceExceededMaximumSizeError) {
// 处理资源超出最大内存限制错误
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Error"
message:@"Resource exceeds maximum memory limit. Please remove some resources and try again."
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
} else if (error.code == NSBundleOnDemandResourceInvalidTagError) {
// 处理无效资源标签错误
NSLog(@"Invalid resource tag: %@", error.localizedDescription);
// 可以进一步确认正确的标签名称并修复 Bug
}
}

@end


You May Also Like

More From Author

+ There are no comments

Add yours