Help writing a change to a variable from within another Type's function

I am very new to SWIFT and have been trying to write a basic digital camera program (as practice) which uses various storage cards, stores the number of photos on the card dependant on the size of file produced by the camera it's been used with. Unfortunately I am having problems changing the value of a mutable Type's property when using a mutating function within another Type!
As you can see below, the code seems to work fine, with the photo count getting bigger as expected when checking the storage card through the camera Type, however when checking the storage card itself, it seems that the value was not written to the declared variable.
I hope I'm using the correct terminology here and apologise if it's rubbish!

import UIKit
import Foundation

//Memory Card Structure
struct MemoryCard {
let make: String
let type: String
let emptyStorage: Int
var photoCount: Int {
    return photosTaken.count
}
var photosTaken: [Int]
var storage: Int {
    return (emptyStorage-photosTaken.reduce(0, +))
}

}

//Declarations of memory cards
var noCardSD = MemoryCard(make: "Sandisk", type: "SD", emptyStorage: 0, photosTaken: [])

//Camera Structure
struct NewCamera {
let make: String
let model: String
var mbPerPhoto: Int
let storageCardType: String
var storageCard: MemoryCard
var remainingStorage: Int {
    let remainStore = storageCard.storage
    return remainStore
}
var remainingPhotos: Int {
    return (storageCard.storage/mbPerPhoto)
}
mutating func takePhoto() {
    if remainingPhotos >= 1 {
       storageCard.photosTaken.append(mbPerPhoto)

    } else {
        print("YOU HAVE INSUFFICIENT STORAGE TO TAKE A PHOTO")
    }
    
}
mutating func takeMultiplePhoto(number:Int) {
    if remainingPhotos >= number {
        storageCard.photosTaken.append(mbPerPhoto*number)
    } else {
        print("YOU HAVE INSUFFICIENT STORAGE FOR THESE PHOTOS")
    }
}
mutating func changeCard(cardType:MemoryCard) {
    if cardType.type == storageCardType {
        storageCard = cardType
    } else {
        print("THIS CARD IS NOT COMPATIBLE WITH THIS CAMERA")
    }
}

}

//Declaring cameras with no cards
var cameraOne = NewCamera(make: "NIKON", model: "D800", mbPerPhoto: 79, storageCardType: "SD", storageCard: noCardSD)
cameraOne.remainingPhotos
var cameraTwo = NewCamera(make: "CANON", model: "D5", mbPerPhoto: 56, storageCardType: "SD", storageCard: noCardSD)

//Declaring New SD cards
var sanDiskSD64 = MemoryCard(make: "Sandisk", type: "SD", emptyStorage: 64000, photosTaken: [])
var sanDiskSD32 = MemoryCard(make: "Sandisk", type: "SD", emptyStorage: 32000, photosTaken: [])

//TESTING

//Place 64GB card in camera
cameraOne.changeCard(cardType: sanDiskSD64)
//Remaining photos function below is correct '''THIS RETURNED 810'''
cameraOne.remainingPhotos
//Take multiple photos with the camera
cameraOne.takeMultiplePhoto(number: 56)
//remaining photos function below is correct '''THIS RETURNED 754'''
cameraOne.remainingPhotos

//However when i check how many photos are contained on the SD card, it says 0!!
sanDiskSD64.photoCount

//I want the sanDiskSD64 variable to contain the photos so if i use it in another camera, it still remembers that the storage has been used. I somehow need to write the data onto the variable??? I have tried this in various ways and failed.

Welcome! In Swift, structs and enums are both value types, which means that when you pass a value of that type or assign it to a different variable, you've made a copy. Future modifications of that copy don't affect the original value, which is why you aren't seeing any effects to sanDiskSD64.

To get the behavior you're expecting, you would need to declare the memory card type as a class, which is a reference type. In that case, changes to the memory card from within the camera would be observable in the original instance.

You can read more about the difference between structs and classes here: Structures and Classes — The Swift Programming Language (Swift 5.7)

3 Likes

That’s great, Thanks for the response! I’ll have a read of that now!