2
votes

Quelle est la meilleure façon d'écrire du code commun et de l'utiliser dans l'ensemble du projet

J'appelle des alertes, des couleurs de vue, des spinners et des propriétés de composants, etc. à partir de la classe partagée. Est-ce une approche correcte. sinon quelle est la meilleure façon d'écrire du code commun et de l'utiliser dans tout le projet.

Ex: mon code de cours partagé est ...

import UIKit

class SharedClass: NSObject {

static let sharedInstance = SharedClass()

    var spinner = UIActivityIndicatorView()

//Show activity indicator
func activityIndicator() {

    DispatchQueue.main.async {
        if let window = UIApplication.shared.keyWindow {//Conditionally unwrap it instead of force unwrap

  //                let window = UIApplication.shared.keyWindow! //Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
            self.transparentView = UIView()
            self.transparentView?.frame = CGRect(x: 0, y: 0, width: window.frame.width, height: window.frame.height)
            self.transparentView?.backgroundColor = UIColor.black.withAlphaComponent(0.4)
            window.addSubview(self.transparentView!)

            if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
                //                    self.spinner = UIActivityIndicatorView(style: .whiteLarge)
                self.spinner = UIActivityIndicatorView(style: .whiteLarge)
                self.spinner.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
            } else {
                //                    self.spinner = UIActivityIndicatorView(style: .white)
                self.spinner = UIActivityIndicatorView(style: .white)
                self.spinner.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
            }
            self.spinner.center = window.center
            self.transparentView?.addSubview(self.spinner)
            self.spinner.startAnimating()

            DispatchQueue.main.asyncAfter(deadline: .now() + 40.0) {//Stop spinner after 40 Sec's
                self.stopActivityIndicator()
            }
        }
    }
}

//Stop activity indicator
func stopActivityIndicator() {
    DispatchQueue.main.async {
        self.spinner.stopAnimating()
        self.spinner.removeFromSuperview()
        self.transparentView?.removeFromSuperview()//Some times getting error here
    }
}

 //Email validation
func isValidEmail(email: String) -> Bool {
    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
    var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
    if valid {
        valid = !email.contains("Invalid email id")
    }
    return valid
}

//Mobile number validation
func isValidPhone(phone: String) -> Bool {
    let phoneRegex = "^((0091)|(\\+91)|0?)[6789]{1}\\d{9}$"; // @"^((0091)|(\\+91)|0?)[6789]{1}\\d{9}$"        "^[0-9]{6,14}$"
    let valid = NSPredicate(format: "SELF MATCHES %@", phoneRegex).evaluate(with: phone)
    return valid
}

 private override init() {

}

}

//Alert function
extension UIViewController {
    func showAlert(title: String, msg: String) {
        DispatchQueue.main.async {
            let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }
}

//Set TF shadow in login VC
extension UITextField {
    func TFProperties() {
        layer.shadowColor = UIColor(red: 199/255, green: 217/255, blue: 223/255, alpha: 1.0).cgColor
        layer.shadowOpacity = 1
        layer.shadowOffset = CGSize.zero
        layer.shadowRadius = 5
        layer.borderColor = UIColor(red: 199/255, green: 217/255, blue: 223/255, alpha: 1.0).cgColor
        layer.borderWidth = 1
        layer.cornerRadius = 4
    }
}

//Set View shadow in OTPVerify VC
extension UIView {
func subViewShadow() {
    layer.shadowColor = UIColor.white.cgColor
    layer.shadowOpacity = 1
    layer.shadowOffset = CGSize.zero
    layer.shadowRadius = 3
    layer.borderColor = UIColor.gray.cgColor
    layer.borderWidth = 1
    layer.cornerRadius = 4
}
func viewShadow() {
    layer.shadowColor = UIColor.gray.cgColor
    layer.shadowOpacity = 1
    layer.shadowOffset = CGSize.zero
    layer.shadowRadius = 3
}
func collectionViewCellBorder() {
    layer.cornerRadius = 5
    layer.borderColor = UIColor UIColor.gray.cgColor
    layer.borderWidth = 1.0
}
}


4 commentaires

écrire des extensions aux classes qui devraient utiliser ce contenu, par exemple pour alert il devrait être UIViewController


J'utilise déjà des extensions, mais je ne sais pas quelle est la meilleure approche. // Extension de fonction d'alerte UIViewController {func showAlert (titre: String, msg: String) {DispatchQueue.main.async {let alert = UIAlertController (titre: titre, message: msg, style préféré: .alert) alert.addAction (UIAlertAction (titre) : "OK", style:. Par défaut, gestionnaire: nil)) self.present (alerte, animé: vrai, complétion: nil)}}}


oui vous avez des extensions et que voudriez-vous faire d'autre?


@ Lu_, j'utilise cette fonction de la classe partagée func isValidEmail (email: String) -> Bool {} est-ce correct ou pas. Et j'utilise aussi spinner ...


3 Réponses :


1
votes

ce que vous faites est juste sachez que c'est un motif singleton. Pour les gestionnaires comme alertViewController, le contrôle du sélecteur, comme la connexion-déconnexion, etc., c'est une bonne utilisation. Il pourrait être appelé et utilisé plusieurs vues différentes. Cela réduit également les duplications de code. Par exemple, vous devez utiliser la feuille d'actions pour deux contrôleurs de vue différents. À ce stade, vous pouvez utiliser un modèle singleton et donner des paramètres extérieurs aux méthodes de cette instance partagée et l'appeler pour vos opérations spécifiques à partir d'un point. Vous n'aurez pas besoin de créer deux contrôleurs d'alerte différents dans chacun de vos contrôleurs :). Utilisez-le à bon escient :).


2 commentaires

@ erkutbas, puis-je savoir ce qu'est login-logout


Par exemple, vous avez une application qui obtient une authentification utilisateur. Login, Register affiche les opérations d'arrière-plan telles que la connexion de l'utilisateur, la déconnexion de l'utilisateur, l'enregistrement de l'utilisateur, les opérations d'oubli de mot de passe peuvent être gérées dans une classe singleton pour toute la hiérarchie de l'application. Parce que dans ces cas, l'application de connexion utilisateur à partir de la vue A, mais la déconnexion de B. C'est pourquoi un modèle de singleton aide le développeur à gérer tout le travail du backend à un seul endroit.



1
votes

C'est une approche correcte si vous pouvez également utiliser @IBDesignable et @IBInspectable pour votre travail lié à la vue, comme ajouter une ombre, un rayon de coin, etc. afin que vous puissiez changer il de votre storyboard également. J'aime.

@IBDesignable extension UIView{

    @IBInspectable
    public var viewCornerRadius: CGFloat{
        set{
            self.layer.cornerRadius = newValue
        }get{
            return self.layer.cornerRadius
        }
    }

    @IBInspectable
    var borderColor: UIColor? {
        get {
            let color = UIColor(cgColor: layer.borderColor!)
            return color
        }
        set {
            layer.borderColor = newValue?.cgColor
        }
    }
    @IBInspectable
    var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }
    @IBInspectable
    var shadowRadius: CGFloat {
        get {
            return layer.shadowRadius
        }
        set {
            layer.shadowRadius = newValue
        }
    }
    @IBInspectable
    var shadowOpacity: Float {
        get {
            return layer.shadowOpacity
        }
        set {
            layer.shadowOpacity = newValue
        }
    }

    @IBInspectable
    var shadowOffset: CGSize {
        get {
            return layer.shadowOffset
        }
        set {
            layer.shadowOffset = newValue
        }
    }
    @IBInspectable
    var shadowColor: UIColor? {
        get {
            if let color = layer.shadowColor {
                return UIColor(cgColor: color)
            }
            return nil
        }
        set {
            if let color = newValue {
                layer.shadowColor = color.cgColor
            } else {
                layer.shadowColor = nil
            }
        }
    }
}


2 commentaires

@ Amit gupta, merci beaucoup. Mais cela semble très difficile, car c'est d'abord que je vois ce code.


ça ne marche pas .. j'ai ajouté un fichier rapide dans mon projet. puis copiez et collez votre code puis changez-le de stroyboard .. mais hors mais pas affiché en direct. quand je lance un projet ça marche bien



3
votes

Créez un cadre commun:

  • XCode> Fichier> Nouveau> Projet>

 Sélection du projet

  • Cadre Cocoa Touch>

 Cocoa Touch Framework

  • Définissez le nom de votre framework (commun, etc.)>

 Common Framework

  • Sélectionnez votre espace de travail principal dans la section "Ajouter à" et "Groupe" et créez>

 Créer un cadre

  • Vous devez lier votre framework aux principales bibliothèques liées cibles>

 Lier le binaire avec les bibliothèques

  • Vous pouvez créer des classes dans votre framework>

 Couleurs dans le cadre

  • Et utilisez le projet principal, importez simplement ce framework comme 'import Common'.

 Utilisation

Remarque: Vous devez utiliser des modificateurs de niveau d'accès sur le framework commun (privé, public, ouvert, etc.).

Modificateurs de niveau d'accès:

Source: Abhimuralidharan's Swift 4 - Article sur le contrôle d'accès

  1. Public: Activer une entité à utiliser en dehors du module de définition (cible).

  2. Privé: L'accès privé limite l'utilisation d'une entité à la déclaration englobante et aux extensions de cette déclaration qui se trouvent dans le même fichier.


6 commentaires

@ Emre Ciftci, très belle réponse ... Aujourd'hui, j'ai appris un nouveau point de votre réponse ...


Salut @iOS. Je suis très reconnaissant pour votre commentaire. Si vous avez accepté, veuillez marquer comme accepté. Prendre plaisir.


@ Emre Ciftci, pouvez-vous expliquer ce qui se passe si nous utilisons private ou open dans la fonction ci-dessus myAppColor . pouvons-nous accéder à l'ensemble de notre projet.


Rebonjour @iOS. Veuillez vérifier ma modification. myAppColor juste un exemple. Si vous utilisez «privé», vous ne pouvez pas utiliser cette propriété dans un autre module. Si vous utilisez «open», vous pouvez utiliser cette propriété dans un autre module et vous pouvez la remplacer. Si vous utilisez 'public', vous pouvez utiliser cette propriété dans un autre module mais ne pouvez pas la remplacer.


@ Emre Ciftci, très sympa ... une dernière question est qu'il est obligatoire d'utiliser des modificateurs de niveau d'accès pour les fonctions ou les variables.


Si des fonctions ou des variables sont dans un module différent et doivent être utilisées en externe (public) ou non (privé), il est nécessaire de les utiliser. Au fait, si vous n'utilisez aucun modificateur de niveau d'accès, réglez swift le modificateur 'internal' sur votre variable / fonction / classe / struct / enum etc.