Uso del analizador de código estático SwiftLint en aplicaciones de banca móvil iOS

Oleg Ivanov, Jefe del Centro de Competencia para Canales de Servicio Remoto



¡Hola a todos! Como se prometió en el artículo "ICD Mobile Bank: Development History" , hoy quiero hablar sobre analizadores de código estático y la experiencia de su aplicación en aplicaciones móviles iOS del banco.

Establezcamos el objetivo que queremos lograr usando este kit de herramientas:

  • detección temprana de errores y deficiencias;
  • Code Style ( — , ).

Una forma común de lograr nuestros objetivos es verificar manualmente el código: revisión de código .

El probador o un grupo de probadores examinan cuidadosamente el código que se está probando, luego identifican errores o secciones del código que pueden volverse erróneos en el futuro, y dan recomendaciones para mejorarlo a través de comentarios sobre el código, que después de un tiempo (!) Serán analizados y corregidos por el desarrollador. Como podemos ver, está surgiendo un proceso de verificación de código largo y costoso. Además, siempre hay un factor humano: los revisores simplemente pueden omitir algunos errores.

Aquí los analizadores de código estático vienen en nuestra ayuda.

Analizadores de Código Estático- Inicie un proceso automatizado para detectar errores y deficiencias en el código fuente de los programas.

Los analizadores de códigos estáticos no son una panacea o un reemplazo para la revisión manual de códigos, pero son una excelente herramienta que le permite reducir el tiempo que lleva realizar las comprobaciones y encontrar rápidamente errores con patrones. La relevancia del uso de analizadores estáticos solo crecerá con el tiempo.

Como analizador de código estático en nuestros proyectos de iOS, usamos SwiftLint.

SwiftLint es una utilidad de comprobación automática de código Swift que se ejecuta durante la fase de construcción de un proyecto. La utilidad contiene un conjunto de reglas con la capacidad de complementar este conjunto con sus reglas personalizadas. La herramienta también se utiliza para cumplir con el estilo de código.

¿Por qué es importante seguir Code Style en la aplicación?
Cuando eres un desarrollador en un proyecto, todo es simple: escribes con tu propio estilo y puedes permitirte el código de esta manera:



Pero cuando trabajas en un gran equipo de desarrollo. Un factor importante es la velocidad de comprensión y de encontrar el lugar para insertar mejoras en el código de otra persona.
Y aquí todos los miembros del equipo tienen que aceptar las convenciones y reglas para escribir código. Pero, ¿cómo verificar su cumplimiento? Una vez más, el analizador de código estático SwiftLint nos ayudará. Y nuestro código tendrá un aspecto agradable que todos los miembros del equipo comprenderán:



para familiarizarse con la herramienta, recomiendo leer la documentación oficial .

Instalar SwiftLint es simple:

  1. Agregue el pod 'SwiftLint' al podfile del proyecto
  2. Agregue una nueva "Fase de ejecución de script" al proyecto.

    "${PODS_ROOT}/SwiftLint/swiftlint"
  3. SwiftLint .swiftlint.yml
  4. .swiftlint.yml , SwiftLint

Si el proyecto de incrustación SwiftLint ya contenía código, tendrá que ser paciente y corregir sistemáticamente todas las recomendaciones de SwiftLint. Los forma a través de las pantallas de error y advertencia habituales con consejos completos sobre las recomendaciones.



También entre paréntesis, muestra el nombre de la regla que inició la recomendación (operator_usage_whitespace) .

En este caso, estos son:

Uso del
operador Espacio en blanco Los operadores deben estar rodeados por un solo espacio.

Código correcto: Código




recomendado:



Cada regla tiene un conjunto de atributos:

Identificador : operator_usage_whitespace
Habilitado por defecto : deshabilitado
Soporte de corrección automática :
Tipo : estilo
Regla del analizador : No
Versión mínima del compilador Swift : 3.0.0
Configuración predeterminada : advertencia

Preste atención a la "Versión mínima del compilador Swift" : correlacione el uso de reglas con este atributo y con la configuración de su proyecto.

Los “Configuración por defecto” de atributos muestra cómo se percibirá reglas con este atributo: o bien una advertencia regular, o un error de compilación, como un moldeada Fuerza regla (configuración por defecto: error)

Todas las reglas se pueden encontrar en un muy conveniente y ilustrada documentación.

A continuación, presentaré las reglas que hemos elegido en nuestro equipo, puede usarlas como ejemplo para crear su proyecto.

Dividimos todas las reglas en funcional y estilístico : sí, sí, sí y un espacio dentro de cada llave, y los parámetros de cierre deben estar en la misma línea que la llave de apertura, y ... :). No pinto las reglas, puede encontrar fácilmente información sobre ellas utilizando el enlace de arriba.

Funcional :

- private_outlet
- force_unwrapping
- force_cast
- force_try
- strong_iboutlet
- private_action
- block_based_kvo
- contains_over_first_not_nil
- discarded_notification_center_observer
- discouraged_direct_init
- discouraged_object_literal
- discouraged_optional_boolean
- discouraged_optional_collection
- duplicate_imports
- dynamic_inline
- empty_count
- empty_parameters
- empty_parentheses_with_trailing_closure
- empty_string
- explicit_enum_raw_value
- function_default_parameter_at_end
- generic_type_name
- identical_operands
- implicit_getter
- is_disjoint
- notification_center_detachment
- nsobject_prefer_isequal
- redundant_set_access_control
- unused_capture_list

El estilo de :

- unneeded_parentheses_in_closure_argument
- let_var_whitespace
- yoda_condition
- Colon
- coma
- closure_parameter_position
- closure_spacing
- collection_alignment
- leading_whitespace
- marca
- opening_brace
- operator_usage_whitespace
- operator_whitespace
- protocol_property_accessors_order
- return_arrow_whitespace
- switch_case_alignment
- statement_position
- trailing_comma
- trailing_newline
- unneeded_break_in_switch
- custom_rules
- closure_end_indentation
- file_name_no_space
- unowned_variable_capture
- no_space_in_method_call
- contiene_sobre_filtro_contacto
- contiene_sobre_filtro_es_empty
- contiene_sobre_nivel_nil_comparación
- duplicate_enum_cases
- empty_collection_literal

también un objetivo de SwiftLint, elegimos solo el catálogo con nuestra base de código agregando la configuración adecuada en el archivo de configuración .swiftlint.yml:

incluido:



creado tu directorio de bases de reglas Funciones de impresión. La impresión es una operación bastante difícil. A través del archivo de configuración .swiftlint.yml:

custom_rules:
  disable_print:
    included: ".*\\.swift"
    name: "print usage"
    regex: "((\\bprint)|(Swift\\.print))\\s*\\("
    message: "Prefer os_log over print"
    severity: error

Esta regla nos impulsó a escribir nuestra función de registro (con un nivel de registro). Los desarrolladores utilizan este registro para la depuración rápida, por ejemplo, los registros con parámetros, un cuerpo de solicitud / respuesta son necesarios para cualquier análisis de errores, para el desarrollo. Para el lanzamiento, el nivel de registro en nuestra versión .none. El resto del uso de la función de impresión dará como resultado un error de compilación para el proyecto.

func logApp(level: Constants.LogLevel, items: Any...) {
    if Constants.logLevel == .none {
        return
    }
    
    if level.rawValue <= Constants.logLevel.rawValue {
        // swiftlint:disable disable_print
        if let strings = items as? [String] {
            for string in strings {
                print(string)
            }
        } else {
            print(items)
        }
        // swiftlunt:enable disable_print
    }

Pero para usar la función de impresión, tuvimos que cerrar su llamada en nuestra función de registro usando SwiftLint para ignorar nuestras propias reglas en un bloque de código marcado con una instrucción especial.

// swiftlint:disable disable_print
// swiftlunt:enable disable_print

SwiftLint tiene la capacidad de ignorar sus propias reglas:

// swiftlint:disable <rule1 [rule2 rule3…]>
<,   SwiftLint   rule1 [rule2 rule3…]>
// swiftlunt:enable <rule1 [rule2 rule3…]>

O

// swiftlint:disable all
<,   SwiftLint   >
// swiftlint:enable all

¡Aprovecha esta oportunidad, consciente de que es necesario!

En conclusión, observo : el uso de SwiftLint en nuestro equipo redujo el costo de la revisión manual del Código en un 20%. Ahora nuestros revisores no prestan atención a los errores típicos (Force Cast, etc.), al estilo de código y pueden concentrarse completamente en verificar el nuevo código. Lo que aumentó significativamente la eficiencia general del equipo (no es necesario corregir tales errores de verificación, estos son empleados calificados, cuyo tiempo es muy importante).

¡Todas! Ahora SwiftLint está para siempre contigo :)


All Articles