Both struct and class are used to define properties to store values. Both can define methods to provide functionality and define initializers. Both can conform to protocols and be extended. Due to so many similarities they are sometimes used alternately by young developers. They are however not the same and in this article you will learn the key differences to better leverage their strengths and create even better projects.
Most noticeable difference between the two is that struct is a value type, while class is a reference type. But what does that mean?
When you copy (assign, initialize or pass to a function) a value type, each instance keeps a unique copy of the data. You can change one instance without changing the other values.

Example:
Jon and Anna go shopping together. Anna prepared a grocery list on a pice of paper. Jon used Anna’s list to create a new one with exactly the same contents on a separate piece of paper. If he added a new item to his list, the two lists would become different because only the list copy would change. Anna’s list would remain the same.
When you copy a reference type, all instances share the data. The reference itself is copied, but not the data it references. Changing one changes all of the other as well because they all refer to the same instance.

Example:
Jon and Anna go shopping together. Anna prepared a grocery list on a pice of paper. Whenever Jon wants to check the list he asks Anna to show him the list she holds. If he added a new item to the list, Anna would also notice the change.
Classes have some additional capabilities that structures simply don’t have. With classes you can use inheritance, meaning that you can create a new class based on an already existing one and inherit its properties and behaviour. You can also use deinitializers to free up any assigned resources. Classes also allow type casting meaning that you can interpret and check the type of a class instance at runtime.
Swift uses Automatic Reference Counting (ARC) for memory management for classes. ARC keeps track of how many references to an instance exist and deallocates the instance when there are no more references. Struct instances on the other hand are managed directly and don't rely on reference counting. It means that structs are generally more lightweight and have better performance characteristics.
Structs are great for simple data types! In my opinion a good rule of thumb is to always start with a struct and only use classes when you need reference semantics or more complex object relationships. You will also need to use classes if you want to use Objective-C interoperability, for example @objc. Remember to always consider the mutability requirements, and whether reference sharing or value copying is more appropriate for your use case.
Check out this collection of short articles dedicated to Swift development!