Search code examples
iosswiftcore-datarealmpersistent-storage

Best way to store complex Swift objects that allows them to be extracted & shipped with app


I'm nearing the end of development of a music-making app, and I want to add the ability to save and load projects/sessions. The app is built around a 'loop machine' that stores recorded notes in multidimensional arrays, and it has many effect parameters and other states that must be saved alongside these arrays. This will be my first time working with data storage in iOS, so I'm looking for some guidance on which system might be best.

I had a look at CoreData and it seems that it would take a very long time to get this data into a suitable form for managed objects. Realm seems like an easier option, as you can save objects 'as is', right? This leads me onto the second part of the question: I'd like to ship some factory projects with the app - is there a way to extract the data saved using Realm (or another method) so that I can ship it with the app ready for the user to load?

Another consideration is how difficult it will be to integrate a data storage system into an existing XCode project.

Here is an extract of the loop machine object to give you an idea of why I think CoreData would be an inefficient method (there are a few other big classes like this):

open class LoopMachine {
   var delegate: LoopMachineDelegate!
   static let defaultTempo = 120
   static let numLoopsPerSource = 3
   static let minLoopLength = 4
   static let maxLoopLength = 32
   static let ticksPerBeat = 32
   var master: Master!
   var sources: Array<LoopSource?>!
   var activeSource = 0
   var beatsPerMeasure = 4
   var currentBeat = 1
   var currentTick = 1
   var metronome = AKMetronome()
   var metronomeOn = true
   var storedTempo: Int! // Used to store the current tempo when it is halved for easy rec mode
   var isPlaying = false
   var isRecording = false
   var countIn = true
   var countingIn = false
   let numSources = 12
   var quantization = 2 // How many ticks to quantize recorded notes to, min: 2 max: ticksPerBeat
   var quantizeNoteOnOnly = true
   var copiedLoop: Loop?
   var copiedLoopType: Int?

This is only my second time posting, so apologies if I've missed anything - just let me know.


Solution

  • It's not clear how much data you will have, but in general it sounds as though you should be looking at a document type persistence, rather than database/Core Data. Have 1 file per project.

    Matt's Codable suggestion is a good place to start looking.

    Save your factory projects as individual files and bundle them as resources in the app.