¿Cómo permite iOS que Lottie use los recursos de la red para la animación?

fondo

Hay una necesidad de usar recursos de CDN para permitir que Lottie haga animaciones, pero debido a que las animaciones necesitan cargar imágenes, la interfaz de inicialización provista por Lottie solo puede cargar configuraciones json, y nadie ha respondido los problemas en Github, así que escribí este artículo para registrar la solución.

Para lograr esta función, incluso volví a ver a Lottie y estaba borracho. . .

plan

El primer punto que debe quedar claro es que si su recurso de Lottie tiene imágenes, entonces usar directamente el método initWithContentsOfURL: de LOTAnimationView no puede cargar automáticamente el recurso de imágenes. Debido a que la carga de imágenes necesita configurar la URL base para LOTComposition, pero al inicializar animatonView a través de url, dado que la configuración json debe cargarse de forma asíncrona, el modelo de escena de la vista está vacío, no puede configurarlo directamente y no hay devolución de llamada para completar la carga dentro la vista, por lo que solo puede pasar Escuchar la configuración de sceneModel o generar un sceneModel para pasar de estas dos formas para realizar la carga de recursos de imagen de Lottie.

La implementación se describe a continuación.

1. Agregue el agente LOTAnimationDelegate para la biblioteca Lottie

Primero, debe implementar el método proxy de solicitud de imagen de LOTAnimationView. Lottie no solicita imágenes internamente y puede usar el método proxy en el método _setImageForAsset: de LOTLayerContainer para enviar la solicitud de imagen al exterior para su implementación. Luego obtenga la imagen y asígnela a self.wrapperLayer.contents, el ejemplo es el siguiente.

- (void)_setImageForAsset:(LOTAsset *)asset {
    ...
    [delegate animationView:asset.animationView fetchResourceWithURL:url completionHandler:^(UIImage * _Nullable image, NSError * _Nullable error) {
        if (image) {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.wrapperLayer.contents = (__bridge id _Nullable)(image.CGImage);
            });
        }
    }];
    ...
}

- (void)animationView:(LOTAnimationView *)animationView fetchResourceWithURL:(NSURL *)url completionHandler:(LOTResourceCompletionHandler)completionHandler {
    [CDNService requestLottieImageWithURL:url completion:^(UIImage * _Nullable image, NSError * _Nullable error) {
        if (completionHandler) {
            completionHandler(image, error);
        }
    }];
}
复制代码

2. Generar LOTComposición

En segundo lugar, dado que la empresa externa no puede percibir directamente el momento de la LOTComposition generada dentro de LOTAnimationView, puede optar por generarla por sí misma y establecer la URL base.

+ (void)requestLottieModelWithURL:(NSURL *)url completion:(void(^)(LOTComposition * _Nullable sceneModel,  NSError * _Nullable error))completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
        NSData *animationData = [NSData dataWithContentsOfURL:url];
        if (!animationData) {
            return;
        }
        NSError *error;
        NSDictionary *animationJSON = [NSJSONSerialization JSONObjectWithData:animationData options:0 error:&error];
        if (error || !animationJSON) {
            if (completion) {
                completion(nil, error);
            }
            return;
        }
        LOTComposition *model = [[LOTComposition alloc] initWithJSON:animationJSON withAssetBundle:[NSBundle mainBundle]];
        dispatch_async(dispatch_get_main_queue(), ^(void) {
            [[LOTAnimationCache sharedCache] addAnimation:model forKey:url.absoluteString];
            //注意,这里的baseURL是你的请求path,需要根据你的业务情况自行设置
            model.baseURL = @"https://os.xxx.cn/lottie/animation/";
            model.cacheKey = url.absoluteString;
            if (completion) {
                completion(model, nil);
            }
        });
    });
}
复制代码

Cabe señalar que la configuración de baseURL de LOTComposition no solo necesita ver el archivo de configuración json de Lottie, sino que también debe prestar atención a la ruta donde el servidor almacena los archivos de Lottie.

假设你有一个叫animation的Lottie资源,那么请先打开配置json观察assets.u的值。这里假设assets.u为"images/",则你需要在服务端存储的文件结构如下:

- animation
    - data.json
    - images
        - img_0.png
        - img_1.png
复制代码

此时,如果json的请求url是https://os.xxx.cn/lottie/animation/data.json ,那么需要给LOTComposition的baseURL设置为https://os.xxx.cn/lottie/animation/

3. 初始化LOTAnimationView

最后只需要请求资源并传给LOTAnimationView即可。

- (LOTAnimationView *)animationView {
    if (!_animationView) {
        //注意,如果想先初始化view再请求资源,不要使用new或者init来初始化
        _animationView = [[LOTAnimationView alloc] initWithFrame:CGRectZero];
        _animationView.animationDelegate = self;
        NSURL *url = [NSURL URLWithString:@"https://os.xxx.cn/lottie/animation/data.json"];
        //请求json配置,生成LOTComposition后传给view
        @weakify(self);
        [CCDNService requestLottieModelWithURL:url completion:^(LOTComposition * _Nullable sceneModel, NSError * _Nullable error) {
            @strongify(self);
            self.animationView.sceneModel = sceneModel;
        }];
    }
    return _animationView;
}
复制代码

Supongo que te gusta

Origin juejin.im/post/7195449060201857084
Recomendado
Clasificación