在目标之间传递数据和变量
Passing data and variables between targets
概览
我正在尝试了解应用程序组,以便我可以将数据和变量从我的主应用程序传递到我的扩展程序,反之亦然。
我发现了什么
我很难理解一些概念,因为我只能找到其他 SO 问题,这些问题仅展示了如何存储和检索数据。
我什至看了 this 教程(并在媒体上阅读了更多内容),但我仍然感到困惑。
我在做什么
首先,我在我的容器应用程序和我的应用程序扩展中启用了应用程序组,并将应用程序组名称设置为 group.grop
。
我有 3 个文件:
- Shared.swift
- 键盘ViewController
- ViewController
在我的 Shared.swift 文件中,我输入了以下代码:
let sharedUserdefaults = UserDefaults(suiteName: SharedDefault.suitName)
struct SharedDefault {
static let suitName = "group.grop"
struct Keys{
static let letters = "letters"
}
}
这里的结构包含我的 suitName 和密钥。
现在,我的键盘扩展如下所示:
在我的键盘 ViewController 中,在视图确实加载后,我输入了以下代码:
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)")
现在我想要发生的是:
- 用户按下键盘上的按钮。
- 一个数字存储在一个数组中。
- 用户打开应用程序,如果他按下 d 按钮,另一个值将存储在数组中。
- 一个标签显示数组中的内容,另一个标签显示数组中元素的数量。
但是使用这种方法我无法从 ViewController 访问 lept
变量。所以我无法向数组添加任何内容,也无法调用 lept.count,例如。
问题
我如何访问(获取值/添加项目/编辑...)来自另一个目标中的目标的变量?
如果您有任何我可以用来更好地研究该主题的信息,请将链接发送给我!
- 将您的
lept
修改为 getter,并始终从 sharedDefaults
: 获取最新值
var lept: [Int] {
return sharedUserdefaults?.array(forKey: SharedDefault.Keys.letters) as? [Int] ?? [Int]()
}
在键盘扩展的 viewDidLoad
中,删除将 lept
数组保存到 sharedDefaults
:
的代码
sharedUserdefaults?.set(lept, forKey: SharedDefault.Keys.letters)
创建一个函数,为每个按钮做同样的事情(下面我将写一些关于所有这些代码的优化):
func appendValue() {
var currentLept = self.lept
currentLept.append(1)
sharedUserdefaults?.set(currentLept, forKey: SharedDefault.Keys.letters)
//print(currentLept) - you can print for debug purposes
}
- 每次按下按钮时调用该函数:
@IBAction func aaction(_ sender: Any) {
appendValue()
}
这是将任何数据从 main target
发送到 extension
的基本逻辑。
优化提示
您应该考虑使用 UICollectionView
来保存所有标签和按钮,并且每个单元格在您的场景中充当按钮或标签。这样,您将创建一个自定义的 UICollectionViewCell 并仅实现所有内容一次,而不是分别处理每个按钮。
根据经验,如果你有任何东西至少重复两次,它要么是一个 tableView,如果你只需要垂直滚动,或者它应该是一个 collectionView,如果你需要水平滚动,或者单元格只占屏幕宽度的一部分。
概览
我正在尝试了解应用程序组,以便我可以将数据和变量从我的主应用程序传递到我的扩展程序,反之亦然。
我发现了什么
我很难理解一些概念,因为我只能找到其他 SO 问题,这些问题仅展示了如何存储和检索数据。
我什至看了 this 教程(并在媒体上阅读了更多内容),但我仍然感到困惑。
我在做什么
首先,我在我的容器应用程序和我的应用程序扩展中启用了应用程序组,并将应用程序组名称设置为 group.grop
。
我有 3 个文件:
- Shared.swift
- 键盘ViewController
- ViewController
在我的 Shared.swift 文件中,我输入了以下代码:
let sharedUserdefaults = UserDefaults(suiteName: SharedDefault.suitName)
struct SharedDefault {
static let suitName = "group.grop"
struct Keys{
static let letters = "letters"
}
}
这里的结构包含我的 suitName 和密钥。
现在,我的键盘扩展如下所示:
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)")
现在我想要发生的是:
- 用户按下键盘上的按钮。
- 一个数字存储在一个数组中。
- 用户打开应用程序,如果他按下 d 按钮,另一个值将存储在数组中。
- 一个标签显示数组中的内容,另一个标签显示数组中元素的数量。
但是使用这种方法我无法从 ViewController 访问 lept
变量。所以我无法向数组添加任何内容,也无法调用 lept.count,例如。
问题
我如何访问(获取值/添加项目/编辑...)来自另一个目标中的目标的变量?
如果您有任何我可以用来更好地研究该主题的信息,请将链接发送给我!
- 将您的
lept
修改为 getter,并始终从sharedDefaults
: 获取最新值
var lept: [Int] {
return sharedUserdefaults?.array(forKey: SharedDefault.Keys.letters) as? [Int] ?? [Int]()
}
在键盘扩展的
的代码viewDidLoad
中,删除将lept
数组保存到sharedDefaults
:sharedUserdefaults?.set(lept, forKey: SharedDefault.Keys.letters)
创建一个函数,为每个按钮做同样的事情(下面我将写一些关于所有这些代码的优化):
func appendValue() {
var currentLept = self.lept
currentLept.append(1)
sharedUserdefaults?.set(currentLept, forKey: SharedDefault.Keys.letters)
//print(currentLept) - you can print for debug purposes
}
- 每次按下按钮时调用该函数:
@IBAction func aaction(_ sender: Any) {
appendValue()
}
这是将任何数据从 main target
发送到 extension
的基本逻辑。
优化提示
您应该考虑使用 UICollectionView
来保存所有标签和按钮,并且每个单元格在您的场景中充当按钮或标签。这样,您将创建一个自定义的 UICollectionViewCell 并仅实现所有内容一次,而不是分别处理每个按钮。
根据经验,如果你有任何东西至少重复两次,它要么是一个 tableView,如果你只需要垂直滚动,或者它应该是一个 collectionView,如果你需要水平滚动,或者单元格只占屏幕宽度的一部分。