У вас есть несколько способов достичь этого.
Наивным решением было бы сделать Block классом, а не структурой. Класс передается по ссылке, а не копируется. Таким образом, изменение в блоке в контроллере будет отражено в API.
Однако это не рекомендуемое решение, поскольку оно приводит к побочным эффектам и усложняет понимание вашего кода в будущем. Ваши модели должны оставаться в виде структур.
Хорошим решением было бы добавить функцию в ваш класс API:
func update(block: Block, surveyId: String) {
// find the survey with the Id surveyId and update its block
}
Я полагаю, что здесь ваша структура опроса имеет некоторый идентификатор, чтобы вы могли может найти его среди других опросов предприятия.
Ваш контроллер должен понравиться
class BlockViewController: UIViewController {
let api: API
let surveyId: String
var block: Block
// ....
}
РЕДАКТИРОВАТЬ: После того, как вы обновили свой вопрос, я думаю, что я понимаю вашу проблему лучше. Когда вы пишете эту строку for var block in blocks
, переменная блока является копией фактического блока, который вы хотите обновить. Так что это не обновляет ваш API.
Ниже приведен пример того, как может выглядеть API. Я взял на себя смелость использовать словари вместо массивов, так как их удобнее обновлять. Настоящий ключ здесь: enterprise.surveys[surveyId]?.update(block: block)
, потому что с помощью нотации [...] ( subscript ) мы получаем доступ для чтения-записи к элементам словаря.
enum BlockStatus {
case answered
case notAnswered
}
struct Block {
typealias Id = Int
let id: Id
var status: BlockStatus
}
struct Survey {
typealias Id = Int
let id: Id
var blocks: [Block.Id: Block]
mutating func update(block: Block) {
blocks[block.id] = block
}
}
struct Enterprise {
var surveys: [Survey.Id: Survey]
}
struct API {
var enterprise: Enterprise
mutating func update(block: Block, surveyId: Survey.Id) {
enterprise.surveys[surveyId]?.update(block: block)
}
func getBlock(id: Block.Id, inSurveyWithId surveyId: Survey.Id) -> Block? {
enterprise.surveys[surveyId]?.blocks[id]
}
}