【问题标题】:Passing data and variables between targets在目标之间传递数据和变量
【发布时间】:2021-01-05 10:01:10
【问题描述】:

概述
我正在尝试了解应用程序组,以便我可以将数据和变量从我的主应用程序传递到我的扩展程序,反之亦然。

我发现了什么
我很难理解一些概念,因为我只能找到其他 SO 问题,这些问题仅说明了如何存储和检索数据。
我什至看过 this 教程(并在 medium 上阅读了更多内容),但我仍然感到困惑。

我在做什么
首先,我在容器应用和应用扩展中都启用了应用组,并将应用组名称设置为 group.grop

我有 3 个文件:

  1. Shared.swift
  2. 键盘视图控制器
  3. 视图控制器

在我的 Shared.swift 文件中,我输入了以下代码:

let sharedUserdefaults = UserDefaults(suiteName: SharedDefault.suitName)
struct SharedDefault {
    static let suitName = "group.grop"
    struct Keys{
        static let letters = "letters"
    }
}

这里的结构包含我的 suitName 和密钥。

现在,我的键盘扩展如下所示:

在我的keyboardViewController中,视图确实加载了,我输入了以下代码:

    var lept: [Int] = sharedUserdefaults?.array(forKey: SharedDefault.Keys.letters) ?? []
    
    @IBOutlet weak var alabel: UILabel!
    @IBOutlet weak var blabel: UILabel!
    @IBOutlet weak var clabel: UILabel!
    
    @IBOutlet weak var abtn: UIButton!
    @IBOutlet weak var bbtn: UIButton!
    @IBOutlet weak var cbtn: UIButton!

在我的 viewDidLoad 内部:

let nib = UINib(nibName: "keygrop", bundle: nil)
              let objects = nib.instantiate(withOwner: self, options: nil)
              view = objects[0] as? UIView

        
        sharedUserdefaults?.set(lept, forKey: SharedDefault.Keys.letters)
        guard let sharedWords = sharedUserdefaults?.array(forKey: SharedDefault.Keys.letters) else {return}
        print ("My words: \(sharedWords)")

在我的 viewDidLoad 下方:

//I have one of these for every button.
 @IBAction func aaction(_ sender: Any) {
        
       lept.append(1)
        sharedUserdefaults?.set(lept, forKey: SharedDefault.Keys.letters)
       print(lept)
    }

在我的 ViewController 中,我有另一个名为 dbutton 的按钮、两个标签和我的视图控制器内的这段代码:

 guard let sharedWordss = sharedUserdefaults?.array(forKey: SharedDefault.Keys.letters) else {return}
        
        print ("My words: \(sharedWordss)")

现在我想要发生的是:

  1. 用户按下键盘上的按钮。
  2. 一个数字被存储在一个数组中。
  3. 用户打开应用程序,如果他按下 d 按钮,另一个值将存储在数组中。
  4. 一个标签显示数组中的内容,另一个标签显示其中元素的数量。

但是使用这种方法我无法从我的 ViewController 访问 lept 变量。因此,我无法向数组中添加任何内容,也无法调用 lept.count。

问题
如何从另一个目标中的目标访问(获取值/添加项目/编辑...)变量?
如果你有什么我可以用来更好地研究这个主题的东西,请将链接发给我!

【问题讨论】:

  • 你保存Int的数组,然后尝试获取Strings的数组?您需要检索Int 的数组。您的 guard 声明没有通过。
  • 这是一个错字,我正在检索一个 int 数组
  • 键盘扩展不与主机应用程序通信。键盘可能出现在不同的应用程序中,而您的应用程序甚至可能没有运行。它们彼此独立。这就是为什么让他们彼此“交谈”的唯一方法是通过保存的信息。
  • @matt 是的,我知道他们是独立的。我如何保存信息?核心数据?
  • matt 想告诉你,交流不会立即发生或反应性发生。您需要将它保存在一个地方,然后从另一个地方的 sharedDefaults 中获取它。它不是像委托那样的通信,也不是回调等。

标签: ios swift keyboard ios-app-extension ios-app-group


【解决方案1】:
  1. 将您的lept 修改为getter,并始终从sharedDefaults 获取最新值:
var lept: [Int] {
    return sharedUserdefaults?.array(forKey: SharedDefault.Keys.letters) as? [Int] ?? [Int]()
}
  1. 在您的键盘扩展的viewDidLoad 中,删除将lept 数组保存到sharedDefaults 的代码:

    sharedUserdefaults?.set(lept, forKey: SharedDefault.Keys.letters)

  2. 创建一个对每个按钮执行相同操作的函数(下面我将针对所有这些代码编写一些优化):

func appendValue() {  
    var currentLept = self.lept
    currentLept.append(1)
    sharedUserdefaults?.set(currentLept, forKey: SharedDefault.Keys.letters)
   //print(currentLept) - you can print for debug purposes
}
  1. 每次按下按钮时调用该函数:
@IBAction func aaction(_ sender: Any) {
        
   appendValue()
}

这是将任何数据从main target 发送到extension 的基本逻辑。

优化提示

您应该考虑使用 UICollectionView 来保存您的所有标签和按钮,并且每个单元格将在您的场景中充当按钮或标签。这样,您将创建一个自定义 UICollectionViewCell 并只实现一次所有内容,而不是单独处理每个按钮。

根据经验,如果你有任何重复至少两次的东西,它要么是一个 tableView,如果你只需要垂直滚动,或者它应该是一个 collectionView,如果你需要水平滚动,或者只占用单元格屏幕宽度的一部分。

【讨论】:

  • 只要我在我的 Mac 上我就试试这个!也非常感谢您提供优化提示。一切都非常感谢
  • 但是如果我想在我的 ViewController 中调用 lept 呢?现在 lept 在键盘视图控制器中
  • 我还有一个问题。现在如果我希望用户从数组中删除一个项目它说我不能编辑它。我如何使它成为可食用的?
  • 函数appendValue() 是一个蓝图,您可以修改sharedDefaults 中的现有数组。首先,将其保存在局部变量中,然后对局部变量进行更改,然后将其保存回 sharedDefaults。仔细看看我在appendValue() 函数中做了什么。
猜你喜欢
  • 2011-07-31
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 2013-07-23
  • 2011-12-03
相关资源
最近更新 更多