如何计算所有类被调用的次数

时间:2018-11-27 04:46:29

标签: ios swift userdefaults

我希望用户能够知道他们访问每个班级的次数。然后将每个页面的总数相加在一起,形成一个分组总和。我想在两个视图控制器的每一个中的日志文件中打印总和。因此只应打印一个字符串。

class oneV: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        UserDefaults.standard.set(true, forKey: "VC1")
    }
}

class twoV: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        UserDefaults.standard.set(true, forKey: "VC2")
    }
}

6 个答案:

答案 0 :(得分:3)

如果您的意思是访问了每个视图控制器,那么当您说访问了每个类时。然后,我建议您这样做viewDidAppear

class YourViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let key = String(describing: type(of: self))
        let count = UserDefaults.standard.value(forKey: key) as? Int ?? 0
        UserDefaults.standard.set(value + 1, forKey: key)
    }

}

为简化起见,您可以在UIViewController上使用扩展名。

extension UIViewController {

    func updateVisitCount() {
        let key = String(describing: type(of: self))
        let count = UserDefaults.standard.value(forKey: key) as? Int ?? 0
        UserDefaults.standard.set(count + 1, forKey: key)
    }

}

或者,如果您需要为创建的每个视图控制器使用此控件,则可以创建一个基本视图控制器,以供您在所有地方使用,而不是UIViewController

class BaseViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        updateVisitCount()
    }

}

答案 1 :(得分:2)

最自动的解决方案是在不替换原始 viewDidLoad的情况下,在viewDidLoad中插入计费呼叫。

在此演示中,我创建了一个示例游乐场

import UIKit
import PlaygroundSupport

extension UIViewController {
    @objc dynamic func substitutedViewDidAppear() {
        print("This is injected code in view did appear")
        substitutedViewDidAppear() // it may look like recursive, but it isn't, actually it calls the original `viewDidAppear` method.
    }

    class func swizzle() {
        let originalMethod = class_getInstanceMethod(UIViewController.self, #selector(viewDidAppear(_:)))
        let substitutedMethod = class_getInstanceMethod(UIViewController.self, #selector(substitutedViewDidAppear))

        if  let originalMethod = originalMethod,
            let substitutedMethod = substitutedMethod {
            print("swizzled")
            method_exchangeImplementations(originalMethod, substitutedMethod)
        } else {
            print("not swizzled")
        }
    }
}

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let label = UILabel()
        label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
        label.text = "Hello World!"
        label.textColor = .black

        view.addSubview(label)
        self.view = view
        print("view loaded")
    }
}

// Swizzle
UIViewController.swizzle() // call this in @top of didFinishLaunchingWithOptions

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

输出:

  

困惑

     

视图已加载

     

这是在视图确实出现的情况下注入的代码

现在在substitutedViewDidAppear的上部,按@Rakesha Shastri的建议插入计数代码,在updateVisitCount内调用substitutedViewDidAppear方法并将UIViewController.swizzle()放在{{1 }},然后再创建根窗口。

答案 2 :(得分:0)

创建一个静态变量。静态变量是类的一种,不是对象,因此在所有对象中都可以维护一个变量。我认为该示例可能会更好地解释其工作原理。点击here

答案 3 :(得分:0)

在ViewDidLoad方法中调用此函数:

func updateVisitingCounter() {

    var counter = UserDefaults.standard.integer(forKey: "firstPageCounter")
    counter += 1
    UserDefaults.standard.set(counter, forKey: "firstPageCounter")

}

答案 4 :(得分:0)

您可以在项目范围的“类之外”设置声明变量

    var vc1Count = 0
    class oneV: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            vc1Count = vc1Count+1
        }
    }

    var vc2Count = 0
    class twoV: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            vc2Count = vc2Count+1
        }
    }

您也可以在公共位置声明这些变量。

答案 5 :(得分:-1)

根据您的要求进行有关应用使用情况的分析。您可以通过两种方式实现

  1. 通过屏幕访问将数据存储在本地数据库中,并将其显示在“分析”页面或“夏季”页面上。

用于在DB中存储屏幕详细信息的示例代码:

==>创建用于屏幕捕获的实体。     屏幕访问。

==>使用屏幕名称存储数据。

let entity = NSEntityDescription.entity(forEntityName: "ScreenVisit", in: context)
let newVisit = NSManagedObject(entity: entity!, insertInto: context)

newVisit.setValue("HomeScreen", forKey: "screenname")
newVisit.setValue("1", forKey: "visited")

do {          
   try context.save()       
  } catch {       
   print("Failed saving")
}

==>在需要的位置获取数据。

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "ScreenVisit")
    //request.predicate = NSPredicate(format: <Your Filter Logic>)
    request.returnsObjectsAsFaults = false
    do {
        let result = try context.fetch(request)
        for data in result as! [NSManagedObject] {
           print(data.value(forKey: "screenname") as! String)
           print(data.value(forKey: "visited") as! String)
      }

    } catch {

        print("Failed")
    }
  1. 您可以使用任何第三方库(例如Google Analytics(分析),Crashlytics(Crashlytics)”来跟踪用户操作。

参考链接:

Firebase iOS analytics

Crashlytics

但是根据我的经验,第二种方式更加方便和强大。

所有取决于您的要求。

希望这将帮助您捕获用户操作。