<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Francesco Leoni</title>
    <description>The latest articles on DEV Community by Francesco Leoni (@francescoleoni98).</description>
    <link>https://dev.to/francescoleoni98</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1098488%2F03811d89-7743-4ed9-af21-648ef4ac7c21.jpeg</url>
      <title>DEV Community: Francesco Leoni</title>
      <link>https://dev.to/francescoleoni98</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/francescoleoni98"/>
    <language>en</language>
    <item>
      <title>How to Create Swift Macros with Xcode 15</title>
      <dc:creator>Francesco Leoni</dc:creator>
      <pubDate>Wed, 21 Jun 2023 06:36:53 +0000</pubDate>
      <link>https://dev.to/francescoleoni98/how-to-create-swift-macros-with-xcode-15-3kll</link>
      <guid>https://dev.to/francescoleoni98/how-to-create-swift-macros-with-xcode-15-3kll</guid>
      <description>&lt;p&gt;&lt;a href="http://blog.leonifrancesco.com/articles/swift-macros"&gt;Here&lt;/a&gt; you can find this articles and many more about iOS and macOS Development.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Macros?
&lt;/h2&gt;

&lt;p&gt;Swift Macros allow you to generate repetitive code at compile time, making your app's codebase more easier to read and less tedious to write.&lt;/p&gt;

&lt;p&gt;There are two types of macros: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Freestanding&lt;/strong&gt; macros stand in place of something else in your code. They always start with a &lt;strong&gt;hashtag&lt;/strong&gt; (#) sign.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="cp"&gt;#caseDetection // Freestanding Macro&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Attached&lt;/strong&gt; macros are used as attributes on declarations in your code. They start with an &lt;strong&gt;@&lt;/strong&gt; sign.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@CaseDetection&lt;/span&gt; &lt;span class="c1"&gt;// Attached Macro&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create new Macro
&lt;/h2&gt;

&lt;p&gt;Macros need to be created in a special &lt;code&gt;Package&lt;/code&gt; that depends on &lt;code&gt;swift-syntax&lt;/code&gt; library.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;SwiftSyntax is a set of Swift libraries for parsing, inspecting, generating, and transforming Swift source code. Here is the &lt;a href="https://github.com/apple/swift-syntax.git"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To create a new Macro go to &lt;code&gt;New -&amp;gt; Package&lt;/code&gt; and select &lt;code&gt;Swift Macro&lt;/code&gt;.&lt;br&gt;
Type the name of your Macro and create the &lt;code&gt;Package&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Type only the actual name of the macro, without Macro suffix. Eg. for a Macro named &lt;strong&gt;AddAsync&lt;/strong&gt;, type &lt;strong&gt;AddAsync&lt;/strong&gt; not &lt;strong&gt;AddAsyncMacro&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Macro Package structure
&lt;/h2&gt;

&lt;p&gt;Inside the newly created &lt;code&gt;Package&lt;/code&gt; you will find some auto-generated files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[Macro name].swift&lt;/code&gt; where you declare the signature of your Macro&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main.swift&lt;/code&gt; where you can test the behaviour of the Macro&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[Macro name]Macro.swift&lt;/code&gt; where you write the actual implementation of the Macro &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[Macro name]Tests.swift&lt;/code&gt;  where you write the tests of the Macro implementation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Macro roles
&lt;/h2&gt;

&lt;p&gt;A single Macro can have multiple roles that will define its behaviour.&lt;br&gt;
The available roles are:&lt;/p&gt;
&lt;h3&gt;
  
  
  @freestanding(expression)
&lt;/h3&gt;

&lt;p&gt;Creates a piece of code that returns a value.&lt;/p&gt;
&lt;h4&gt;
  
  
  Protocol
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;ExpressionMacro&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Declaration
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@freestanding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  @freestanding(declaration)
&lt;/h3&gt;

&lt;p&gt;Creates one or more declarations. Like &lt;code&gt;struct&lt;/code&gt;, &lt;code&gt;function&lt;/code&gt;, &lt;code&gt;variable&lt;/code&gt; or &lt;code&gt;type&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Protocol
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;DeclarationMacro&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Declaration
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@freestanding&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arbitrary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  @attached(peer)
&lt;/h3&gt;

&lt;p&gt;Adds new declarations alongside the declaration it's applied to.&lt;/p&gt;
&lt;h4&gt;
  
  
  Protocol
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;PeerMacro&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Declaration
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;overloaded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  @attached(accessor)
&lt;/h3&gt;

&lt;p&gt;Adds accessors to a property. Eg. adds &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt; to a &lt;code&gt;var&lt;/code&gt;. For example the &lt;code&gt;@State&lt;/code&gt; in SwiftUI.&lt;/p&gt;
&lt;h4&gt;
  
  
  Protocol
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;AccessorMacro&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Declaration
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  @attached (memberAttribute)
&lt;/h3&gt;

&lt;p&gt;Adds attributes to the declarations in the type/extension it's applied to.&lt;/p&gt;
&lt;h4&gt;
  
  
  Protocol
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;MamberAttributeMacro&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Declaration
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memberAttribute&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  @attached (member)
&lt;/h3&gt;

&lt;p&gt;Adds new declarations inside the type/extension it's applied to. Eg. adds a custom &lt;code&gt;init()&lt;/code&gt; inside a &lt;code&gt;struct&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Protocol
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;MemberMacro&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Declaration
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;named&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  @attached(conformance)
&lt;/h3&gt;

&lt;p&gt;Adds conformances to protocols.&lt;/p&gt;
&lt;h4&gt;
  
  
  Protocol
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;ConformanceMacro&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Declaration
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conformance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Build Macro
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Signature
&lt;/h3&gt;

&lt;p&gt;In this guide we will create a &lt;strong&gt;Macro&lt;/strong&gt; that creates an &lt;code&gt;async&lt;/code&gt; function off of a &lt;code&gt;completion&lt;/code&gt; one.&lt;br&gt;
To start building this Macro we need to create the Macro &lt;strong&gt;signature&lt;/strong&gt;.&lt;br&gt;
To do this, go to &lt;code&gt;[Macro name].swift&lt;/code&gt; file and add.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;overloaded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;macro&lt;/span&gt; &lt;span class="kt"&gt;AddAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;externalMacro&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"AddAsyncMacros"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"AddAsyncMacro"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you declare the name of the Macro (&lt;code&gt;AddAsync&lt;/code&gt;), then in the &lt;code&gt;#externalMacro&lt;/code&gt; you specify the module it is in and the type of the Macro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;Then to implement the actual Macro, go to the &lt;code&gt;[Macro name]Macro.swift&lt;/code&gt; file.&lt;br&gt;
Create a &lt;code&gt;public struct&lt;/code&gt; named accordingly with the name of the Macro and add conformance to protocols based on the signature you specified in the &lt;code&gt;Macro signature&lt;/code&gt;. &lt;br&gt;
So, inside newly created &lt;code&gt;struct&lt;/code&gt; and add the required method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;AddAsyncMacro&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PeerMacro&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;expansion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="nv"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;AttributeSyntax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;providingPeersOf&lt;/span&gt; &lt;span class="nv"&gt;declaration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;DeclSyntaxProtocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;MacroExpansionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throws&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;DeclSyntax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Implement macro&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your &lt;code&gt;Macro signature&lt;/code&gt; has more than one role you need to add conformance to each role, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Signature&lt;/span&gt;
&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memberAttribute&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;@attached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;named&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;macro&lt;/span&gt; &lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="c1"&gt;// Implementation&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;MyMacro&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;AccessorMacro&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;MamberAttributeMacro&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;MemberMacro&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;To know the corresponding protocols see Macro roles section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Exporting the Macro
&lt;/h3&gt;

&lt;p&gt;Inside &lt;code&gt;[Macro name]Macro.swift&lt;/code&gt; file add or edit this piece of code with to newly created Macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@main&lt;/span&gt;
&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;AddAsyncMacroPlugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CompilerPlugin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;providingMacros&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;SwiftSyntaxMacros&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Macro&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="kt"&gt;AddAsyncMacro&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Expansion method
&lt;/h3&gt;

&lt;p&gt;The expansion method is responsible for generating the hidden code.&lt;br&gt;
Here the piece of code the &lt;strong&gt;Macro&lt;/strong&gt; (&lt;code&gt;declaration&lt;/code&gt;) is attached on, is broken into pieces (&lt;code&gt;TokenSyntax&lt;/code&gt;) and manipulated to generate the desired additional code.&lt;/p&gt;

&lt;p&gt;To do this we have to cast the &lt;code&gt;declaration&lt;/code&gt; to the desired syntax. &lt;br&gt;
Eg. If the Macro can be attached to a &lt;code&gt;struct&lt;/code&gt; we will cast it to &lt;code&gt;StructDeclSyntax&lt;/code&gt;.&lt;br&gt;
In this case the Macro can only be attached to a &lt;code&gt;function&lt;/code&gt; so we will cast it to &lt;code&gt;FunctionDeclSyntax&lt;/code&gt;.&lt;br&gt;
So, inside the &lt;code&gt;expansion&lt;/code&gt; method add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;functionDecl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FunctionDeclSyntax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// TODO: Throw error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, before we continue, we need to write a test that checks whether the implementation of the Macro generates the code we expect.&lt;br&gt;
So, in &lt;code&gt;[Macro name]Tests.swift&lt;/code&gt; file add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;test_AddAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;assertMacroExpansion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"""
        @AddAsync
        func test(arg1: String, completion: (String?) -&amp;gt; Void) {

        }
        """&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;expandedSource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"""

        func test(arg1: String, completion: (String?) -&amp;gt; Void) {

        }

        func test(arg1: String) async -&amp;gt; String? {
          await withCheckedContinuation { continuation in
            self.test(arg1: arg1) { object in
              continuation.resume(returning: object)
            }
          }
        }
        """&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;macros&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;testMacros&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is in place, let's add a breakpoint at &lt;code&gt;return []&lt;/code&gt; inside the &lt;code&gt;expansion&lt;/code&gt; method and run the test.&lt;br&gt;
Once we hit the breakpoint, run &lt;code&gt;po functionDecl&lt;/code&gt; inside the debug console to get this long description:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;FunctionDeclSyntax
├─attributes: AttributeListSyntax
│ ╰─[0]: AttributeSyntax
│   ├─atSignToken: atSign
│   ╰─attributeName: SimpleTypeIdentifierSyntax
│     ╰─name: identifier("AddAsync")
├─funcKeyword: keyword(SwiftSyntax.Keyword.func)
├─identifier: identifier("test")
├─signature: FunctionSignatureSyntax
│ ╰─input: ParameterClauseSyntax
│   ├─leftParen: leftParen
│   ├─parameterList: FunctionParameterListSyntax
│   │ ├─[0]: FunctionParameterSyntax
│   │ │ ├─firstName: identifier("arg1")
│   │ │ ├─colon: colon
│   │ │ ├─type: SimpleTypeIdentifierSyntax
│   │ │ │ ╰─name: identifier("String")
│   │ │ ╰─trailingComma: comma
│   │ ╰─[1]: FunctionParameterSyntax
│   │   ├─firstName: identifier("completion")
│   │   ├─colon: colon
│   │   ╰─type: FunctionTypeSyntax
│   │     ├─leftParen: leftParen
│   │     ├─arguments: TupleTypeElementListSyntax
│   │     │ ╰─[0]: TupleTypeElementSyntax
│   │     │   ╰─type: OptionalTypeSyntax
│   │     │     ├─wrappedType: SimpleTypeIdentifierSyntax
│   │     │     │ ╰─name: identifier("String")
│   │     │     ╰─questionMark: postfixQuestionMark
│   │     ├─rightParen: rightParen
│   │     ╰─output: ReturnClauseSyntax
│   │       ├─arrow: arrow
│   │       ╰─returnType: SimpleTypeIdentifierSyntax
│   │         ╰─name: identifier("Void")
│   ╰─rightParen: rightParen
╰─body: CodeBlockSyntax
  ├─leftBrace: leftBrace
  ├─statements: CodeBlockItemListSyntax
  ╰─rightBrace: rightBrace
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you can see every component of the function declaration.&lt;br&gt;
And now you can pick the individual piece you need and use it to create you Macro-generated code.&lt;/p&gt;
&lt;h3&gt;
  
  
  Retrieve first argument name
&lt;/h3&gt;

&lt;p&gt;For example, if you need to retrieve the first argument name of the function, you will write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;functionDecl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FunctionSignatureSyntax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;parameters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parameterList&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;firstParameter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;parameterName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstParameter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; arg1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is quite a long code just to retrieve a single string and it will be even more complex if you need to handle multiple function variations.&lt;br&gt;
I think that Apple will improve this in the future, but for now let's stick with this.&lt;/p&gt;
&lt;h3&gt;
  
  
  Complete the implementation
&lt;/h3&gt;

&lt;p&gt;Now, let's complete the &lt;code&gt;AddAsync&lt;/code&gt; implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;functionDecl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FunctionSignatureSyntax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;parameters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parameterList&lt;/span&gt;

   &lt;span class="c1"&gt;// 1.&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;completion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;completionType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;completion&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FunctionTypeSyntax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;remainPara&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FunctionParameterListSyntax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removingLast&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="c1"&gt;// 2. returns "arg1: String"&lt;/span&gt;
   &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;functionArgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;remainPara&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;paraType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SimpleTypeIdentifierSyntax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;paraType&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;joined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;separator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;", "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="c1"&gt;// 3. returns "arg1: arg1"&lt;/span&gt;
   &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;calledArgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;remainPara&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;joined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;separator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;", "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="c1"&gt;// 4.&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="s"&gt;"""
   func &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;functionDecl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="nv"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;functionArgs&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;) async -&amp;gt; &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;completionType&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt; {
      await withCheckedContinuation { continuation in
         self.&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;functionDecl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="nv"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calledArgs&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;) { object in
            continuation.resume(returning: object)
         }
      }
   }
   """&lt;/span&gt;
   &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this block of code we:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve the completion argument from the function signature&lt;/li&gt;
&lt;li&gt;Parse the function arguments except the completion&lt;/li&gt;
&lt;li&gt;Create the arguments that get passed into the called function&lt;/li&gt;
&lt;li&gt;Compose the async function&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Show custom errors
&lt;/h2&gt;

&lt;p&gt;Macros allow you to show custom errors to the user.&lt;br&gt;
For example, in case the user placed the macro on a &lt;code&gt;struct&lt;/code&gt; but that macro can only be used with &lt;code&gt;functions&lt;/code&gt;.&lt;br&gt;
In this case, you can throw an error and it will be automatically shown in Xcode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="kt"&gt;AsyncError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;CustomStringConvertible&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;onlyFunction&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;onlyFunction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"@AddAsync can be attached only to functions."&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Inside `expansion` method. &lt;/span&gt;
&lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;functionDecl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;declaration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FunctionDeclSyntax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="kt"&gt;AsyncError&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onlyFunction&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- Error thrown here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test Macro usage
&lt;/h2&gt;

&lt;p&gt;To test the behaviour of the &lt;code&gt;AddAsync&lt;/code&gt; macro.&lt;br&gt;
Go to the &lt;code&gt;main.swift&lt;/code&gt; file and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;AsyncFunctions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;@AddAsync&lt;/span&gt;
  &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="kt"&gt;AsyncFunctions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Blob"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see the build completes with success.&lt;br&gt;
!WARNING The autocompletion may not show the generated async function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show Macro generated code
&lt;/h2&gt;

&lt;p&gt;To expand a Macro in code and see the automatically generated code, &lt;code&gt;right click&lt;/code&gt; on the Macro and choose &lt;code&gt;Expand Macro&lt;/code&gt; from the menu.&lt;br&gt;
!WARNING The &lt;code&gt;Expand Macro&lt;/code&gt; seems to not work always in Xcode 15.0 beta (15A5160n).&lt;/p&gt;

&lt;h2&gt;
  
  
  Breakpoint
&lt;/h2&gt;

&lt;p&gt;Code generated by Macros can be debugged by adding breakpoints as you normally would.&lt;br&gt;
To do this, &lt;code&gt;right click&lt;/code&gt; on a Macro and choose &lt;code&gt;Expand Macro&lt;/code&gt; from the menu.&lt;br&gt;
Then add a breakpoints at the line you wish to debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations! You just created your first Macro.&lt;br&gt;
Check out &lt;a href="https://github.com/francescoleoni98/Swift-Macros-AddAsync-example"&gt;here&lt;/a&gt; the complete code.&lt;br&gt;
As you saw, so far Macro implementations can be quite long event to perform a simple task.&lt;br&gt;
But once you wrap your head around, they can be really useful and they can save you a lot of boilerplate code.&lt;br&gt;
Macros are still in Beta so I think Apple will improve them by the time they will be available publicly.&lt;br&gt;
Thank you for reading&lt;/p&gt;

</description>
      <category>swift</category>
      <category>ios</category>
      <category>development</category>
      <category>apple</category>
    </item>
    <item>
      <title>Introducing SwiftData the successor of CoreData</title>
      <dc:creator>Francesco Leoni</dc:creator>
      <pubDate>Wed, 14 Jun 2023 08:47:31 +0000</pubDate>
      <link>https://dev.to/francescoleoni98/introducing-swiftdata-the-successor-of-coredata-1n5c</link>
      <guid>https://dev.to/francescoleoni98/introducing-swiftdata-the-successor-of-coredata-1n5c</guid>
      <description>&lt;p&gt;&lt;a href="https://blog.leonifrancesco.com"&gt;Here&lt;/a&gt; you can find this articles and many more about iOS and macOS Development.&lt;/p&gt;

&lt;p&gt;SwiftData is a framework for data modelling and management.&lt;br&gt;
It's built on top of CoreData's  persistence layer, but with an API completely redesigned and reimagined for Swift.&lt;br&gt;
SwiftData provides also support for undo and redo automatically. &lt;br&gt;
And if your app have shared container enabled, SwiftData automatically makes data directly accessible by widgets using the same APIs.&lt;br&gt;
Now, let's see how it works.&lt;/p&gt;
&lt;h2&gt;
  
  
  Models
&lt;/h2&gt;

&lt;p&gt;First we need to create the models that we want to persist.&lt;br&gt;
To create a model you need to mark the &lt;code&gt;class&lt;/code&gt; with the Macro &lt;code&gt;@Model&lt;/code&gt;.&lt;br&gt;
SwiftData includes all non-computed properties of a class as long as they use compatible types. So far, SwiftData supports types such as &lt;code&gt;Bool&lt;/code&gt;, &lt;code&gt;Int&lt;/code&gt; and &lt;code&gt;String&lt;/code&gt;, as well as &lt;code&gt;structures&lt;/code&gt;, &lt;code&gt;enumerations&lt;/code&gt;, and other value types that conform to the &lt;code&gt;Codable&lt;/code&gt; protocol.&lt;br&gt;
So, let's create the &lt;code&gt;Folder&lt;/code&gt; and  &lt;code&gt;Note&lt;/code&gt; models.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Model&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Folder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;@Attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuidString&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;creationDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Date&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;creationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;@Model&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Decodable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;@Attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuidString&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

  &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a model class that contains all the properties you wish to persist&lt;/li&gt;
&lt;li&gt;Mark the classes with the Macro &lt;code&gt;@Model&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Optionally, add Macros (&lt;code&gt;@Attribute&lt;/code&gt;, &lt;code&gt;@Relationship&lt;/code&gt;, &lt;code&gt;@Transient&lt;/code&gt;) to the property that need them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Creating models is as simple as that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt;: As for now, if you declare an array of objects is likely you will get an error like &lt;code&gt;Ambiguous use of 'getValue(for:)'&lt;/code&gt;. This is a bug in Xcode 15.0 beta that I think will be fixed on final version of Xcode. For now, just remove the &lt;code&gt;@Model&lt;/code&gt; from the &lt;code&gt;Note&lt;/code&gt; class and add &lt;code&gt;@Transient()&lt;/code&gt; to &lt;code&gt;notes&lt;/code&gt; property.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Model attributes
&lt;/h2&gt;

&lt;p&gt;Properties in the &lt;code&gt;@Model&lt;/code&gt; can have &lt;a href="https://dev.to/articles/swift-macros"&gt;Macros&lt;/a&gt; attached to them that will defined their behaviour.&lt;br&gt;
Currently there are 3 types of macros: &lt;a href="https://developer.apple.com/documentation/swiftdata/attribute%28_:renamingidentifier:hashmodifier:%29"&gt;&lt;code&gt;@Attribute&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://developer.apple.com/documentation/swiftdata/relationship%28_:_:renamingidentifier:inverse:hashmodifier:%29"&gt;&lt;code&gt;@Relationship&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://developer.apple.com/documentation/swiftdata/transient"&gt;&lt;code&gt;@Transient&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  @Attribute
&lt;/h3&gt;

&lt;p&gt;This Macro alters how SwiftData handles the persistence of a particular model property.&lt;br&gt;
This is commonly used to mark a property as primary key, as we did for &lt;code&gt;Folder.id&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But there are many other options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;encrypt&lt;/code&gt;:  Stores the property’s value in an encrypted form.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;externalStorage&lt;/code&gt;: Stores the property’s value as binary data adjacent to the model storage.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;preserveValueOnDeletion&lt;/code&gt;: Preserves the property’s value in the persistent history when the context deletes the model.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spotlight&lt;/code&gt;: Indexes the property’s value so it can appear in Spotlight search results.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;transformable&lt;/code&gt;: Transforms the property’s value between an in-memory form and a persisted form.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;transient&lt;/code&gt;: Enables to the context to disregard the property when saving the model.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unique&lt;/code&gt;: Ensures the property’s value is unique across all models of the same type.
### @Relationship
By default if you declare a property whose type is also a model, SwiftData manages the relationship between these models automatically.
But if you want to customise its behaviour, you can use the &lt;code&gt;@Relationship&lt;/code&gt; Macro.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way if the &lt;code&gt;Folder&lt;/code&gt; is deleted, all of its notes are deleted too.&lt;br&gt;
This Macro defines the behaviour that in CoreData was named &lt;strong&gt;Delete Rule&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Both &lt;code&gt;@Attribute&lt;/code&gt; and &lt;code&gt;@Relationship&lt;/code&gt; support the renaming of the  argument in case you want to preserve the original name of the property.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  @Transient
&lt;/h3&gt;

&lt;p&gt;By default SwiftData persist all non-computed properties inside the model, but if you don't need to persist a specific property, you can add the &lt;code&gt;@Transient&lt;/code&gt; Macro to that property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Transient&lt;/span&gt; 
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;someTempProperty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The model container
&lt;/h2&gt;

&lt;p&gt;Before using these models, we need to tell SwiftData which models to persist.&lt;br&gt;
To do this there is the &lt;code&gt;.modelContainer&lt;/code&gt; modifier. To use it you simply pass all the models you want to persist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@main&lt;/span&gt;
&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;NoteBookApp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;Scene&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kt"&gt;WindowGroup&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kt"&gt;ContentView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modelContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Folder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we pass only the &lt;code&gt;Folder&lt;/code&gt; class because SwiftData knows that it has to persist also &lt;code&gt;Note&lt;/code&gt; since there is a relationship between the two classes.&lt;br&gt;
The &lt;code&gt;.modelContainer&lt;/code&gt; modifer allows you to specify some options.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;inMemory&lt;/code&gt;: Whether the container should store data only in memory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isAutosaveEnabled&lt;/code&gt;: If enabled you don't need to save changes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isUndoEnabled&lt;/code&gt;: Allows you to undo or redo changes to the context.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onSetup&lt;/code&gt;: A callback that will be invoked when the creation of the container has succeeded or failed.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: If you model contains a relationship to another model, you can omit the destination model.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Saving models
&lt;/h2&gt;

&lt;p&gt;Now, we are ready to use SwiftData.&lt;br&gt;
Let's see how to save models.&lt;br&gt;
First we need to get the context, to do this we use the &lt;code&gt;@Environment(\.modelContext)&lt;/code&gt; wrapper.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Environment&lt;/span&gt;&lt;span class="p"&gt;(\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, once we have the context, we create the object we want to save and we insert it into the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Folder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Trips"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we have enabled the autosaving while creating the container we don't have to do anything else.&lt;br&gt;
Otherwise we need to save the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hasChanges&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fetching models
&lt;/h2&gt;

&lt;p&gt;To fetch existing models, SwiftData provides the &lt;code&gt;@Query&lt;/code&gt; wrapper.&lt;br&gt;
This wrapper allows you to sort, filter and order the result of the query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="kt"&gt;Predicate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;  &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;  &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;folders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Folder&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we query by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filter folders that have non-empty name&lt;/li&gt;
&lt;li&gt;Sort them by the &lt;code&gt;name&lt;/code&gt; property&lt;/li&gt;
&lt;li&gt;Order them ascending&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or, we can use a &lt;code&gt;FetchDescriptor&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;FetchDescriptor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;byName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;FetchDescriptor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Folder&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;descriptor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FetchDescriptor&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Folder&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nv"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="kt"&gt;Predicate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nv"&gt;sortBy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;SortDescriptor&lt;/span&gt;&lt;span class="p"&gt;(\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;descriptor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;descriptor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;includePendingChanges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;descriptor&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;@Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;byName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Folder&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way we can reuse the &lt;code&gt;FetchDescriptor&lt;/code&gt; for as many queries as we need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating models
&lt;/h2&gt;

&lt;p&gt;To update a model we just need to change the value of the property we want and if autosave is enabled that's all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"New name"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise we need to save the context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deleting models
&lt;/h2&gt;

&lt;p&gt;To delete a model is just as simple as to create one.&lt;br&gt;
We get the instance of the object to delete and we pass it to the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;SwiftData really simplifies the usage of CoreData, making it less prone to errors.&lt;br&gt;
Of course this is still in Beta so there will be changes and improvements, but so far I really enjoyed playing with it.&lt;br&gt;
Hope this will help developers speed up their workflow to persist data and reduce crashes.&lt;br&gt;
Thank you for reading!&lt;br&gt;
What are you thoughts about this? Tweet me &lt;a href="https://twitter.com/intent/tweet?original_referer=http%3A%2F%2Fblog.leonifrancesco.com%2F&amp;amp;ref_src=twsrc%5Etfw%7Ctwcamp%5Ebuttonembed%7Ctwterm%5Eshare%7Ctwgr%5E7C%20SwiftyLion&amp;amp;url=https%3A%2F%2Fblog.leonifrancesco.com%2Farticles%2Fintroducing-swift-data-the-successor-of-coredata&amp;amp;via=franceleonidev"&gt;@franceleonidev&lt;/a&gt; and share your opinion.&lt;/p&gt;

</description>
      <category>swift</category>
      <category>xcode</category>
      <category>database</category>
      <category>swiftui</category>
    </item>
    <item>
      <title>Combine CoreData and SwiftUI</title>
      <dc:creator>Francesco Leoni</dc:creator>
      <pubDate>Fri, 09 Jun 2023 15:26:15 +0000</pubDate>
      <link>https://dev.to/francescoleoni98/combine-coredata-and-swiftui-3ae5</link>
      <guid>https://dev.to/francescoleoni98/combine-coredata-and-swiftui-3ae5</guid>
      <description>&lt;p&gt;Recently I had to build an app using &lt;strong&gt;SwiftUI&lt;/strong&gt; and &lt;strong&gt;CoreData&lt;/strong&gt;.&lt;br&gt;
I thought CoreData was used almost as you would use it with UIKit, but apparently there are some differences.&lt;br&gt;
This guide is intended as a summary of my experience using CoreData combined with SwiftUI. If I will find other aspects, I will add them to this guide.&lt;br&gt;
So, without further ado, let's begin.&lt;/p&gt;
&lt;h2&gt;
  
  
  Set-up
&lt;/h2&gt;

&lt;p&gt;This is a pretty straightforward part.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you start a new project you can check the '&lt;strong&gt;Use Core Data&lt;/strong&gt;' option and '&lt;strong&gt;Host in CloudKit&lt;/strong&gt;' if you want to save your users data to the cloud. In this case XCode will take care of setting up the project for you. (For the CloudKit part will need to do some extra steps).&lt;/li&gt;
&lt;li&gt;If you have already a project you'll need to create a &lt;strong&gt;Persistence.swift&lt;/strong&gt; file and a swift file where you initialise the CoreData stack. (You can even create a new project following the previous step, and copy the &lt;strong&gt;Persistence.swift&lt;/strong&gt; file generated by XCode to your project.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Setup the &lt;a class="mentioned-user" href="https://dev.to/main"&gt;@main&lt;/a&gt; app
&lt;/h3&gt;

&lt;p&gt;Now that you have your project, to be able to use CoreData within your &lt;code&gt;View&lt;/code&gt;s, you need to pass the &lt;code&gt;managedObjectContext&lt;/code&gt; down you view hierarchy.&lt;br&gt;
Usually this is done in your &lt;strong&gt;App.swift&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@main&lt;/span&gt;
&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ExampleApp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;persistenceController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;PersistenceController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;

  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;Scene&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;WindowGroup&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;ContentView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;environmentObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;persistenceController&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;(\\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;managedObjectContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;persistenceController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;viewContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Personally I pass, as an &lt;code&gt;.environmentObject&lt;/code&gt;, the &lt;strong&gt;PersistenceController&lt;/strong&gt; itself. Because I like to keep all the CRUD logic inside that struct, but that's up to you. If you want to do so you need to make your &lt;strong&gt;PersistenceController&lt;/strong&gt; struct conform to &lt;strong&gt;ObservableObject&lt;/strong&gt;.&lt;br&gt;
Great, now you're able to create, read, update and delete &lt;code&gt;NSManagedObjects&lt;/code&gt; in your &lt;code&gt;View&lt;/code&gt;s.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;: &lt;strong&gt;PersistenceController&lt;/strong&gt; (&lt;a href="https://blog.leonifrancesco.com/articles/persistence-controller"&gt;here is an exemple&lt;/a&gt;) is the struct that XCode generates  automatically for you when you start a new project with the '&lt;strong&gt;Use Core Data&lt;/strong&gt;' option checked.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Operating with CoreData
&lt;/h2&gt;

&lt;p&gt;To operate with CoreData in your &lt;code&gt;View&lt;/code&gt; you need to access the &lt;code&gt;NSManagedObjectContext&lt;/code&gt;. To do so, you have two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the &lt;strong&gt;@Environment&lt;/strong&gt; wrapper in your &lt;code&gt;View&lt;/code&gt;s
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Environment&lt;/span&gt;&lt;span class="p"&gt;(\\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;managedObjectContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;viewContext&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Using the &lt;strong&gt;@EnvironmentObject&lt;/strong&gt; wrapper to get your controller, and from it you can access the &lt;code&gt;viewContext&lt;/code&gt; or CRUD methods
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@EnvironmentObject&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;persistenceController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PersistenceController&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Saving the context
&lt;/h2&gt;

&lt;p&gt;You can save the context using the &lt;code&gt;.save()&lt;/code&gt; method of &lt;code&gt;NSManagedObjectContext&lt;/code&gt;. Before saving the context you can check whether  there are some changes, and save it only if they are present.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;viewContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hasChanges&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;viewContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Saving objects
&lt;/h2&gt;

&lt;p&gt;To save a &lt;code&gt;NSManagedObject&lt;/code&gt; you first need to instanciate it and than configure its properties. And then save the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;viewContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;folder&lt;/span&gt;
&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;creationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;saveContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;: You can animate this insertion wrapping this code inside the &lt;code&gt;withAnimation&lt;/code&gt; function of SwiftUI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Fetching objects
&lt;/h2&gt;

&lt;p&gt;Now the fetching part, this is where I found the most difficulties. Let's start right away.&lt;br&gt;
To fetch objects in SwiftUI the most convenient way of doing it is using the &lt;strong&gt;@FetchRequest&lt;/strong&gt; or &lt;strong&gt;@SectionedFetchRequest&lt;/strong&gt;  wrappers, in every single &lt;code&gt;View&lt;/code&gt; you need to read from CoreData.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt;: Passing fetched objects between &lt;code&gt;View&lt;/code&gt;s will break the automatic updates in case you add, edit or delete objects. (If you know a way to pass fetch objects without breaking the updates let me know and I will update this guide)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you need to add a &lt;strong&gt;@FetchRequest&lt;/strong&gt; in every &lt;code&gt;View&lt;/code&gt; you need CoreData objects and automatic updates. I know it is a bit annoying but it will be worth it.&lt;br&gt;
So, with that said the code is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@FetchRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
              &lt;span class="nv"&gt;sortDescriptors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;NSSortDescriptor&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="nv"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSPredicate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nv"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;FetchedResults&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, if you want your objects grouped by a property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@SectionedFetchRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                       &lt;span class="nv"&gt;sectionIdentifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\\&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="nv"&gt;sortDescriptors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;NSSortDescriptor&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                       &lt;span class="nv"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSPredicate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="nv"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;SectionedFetchResults&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;YourSectionType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use these sections you just pass them to a &lt;code&gt;List&lt;/code&gt; or &lt;code&gt;ForEach&lt;/code&gt;, and then to another &lt;code&gt;ForEach&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="kt"&gt;Section&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
      &lt;span class="c1"&gt;// Configure your view with the object&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;: If you use &lt;strong&gt;@SectionedFetchRequest&lt;/strong&gt; with sorting you may need to specify two sort descriptor. The first will sort the sections and the second one will take care of the objects inside each section. This feature is really useful and requires very little effort.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using &lt;strong&gt;@FetchRequest&lt;/strong&gt; or &lt;strong&gt;@SectionedFetchRequest&lt;/strong&gt; wherever you add, update or delete an object, the views are automatically updated.&lt;br&gt;
Now, if you need to use a &lt;strong&gt;@FetchRequest&lt;/strong&gt; with a &lt;code&gt;NSPredicate&lt;/code&gt; that has a parameter passed from the parent &lt;code&gt;View&lt;/code&gt;, I found that the next option works wonderfully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@FetchRequest&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;FetchedResults&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;_objects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FetchRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;predicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSPredicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"id == %@"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way you can pass your parameter in the &lt;code&gt;init&lt;/code&gt; and use it to filter your results while keeping the automatic updates. The same goes for &lt;strong&gt;@SectionedFetchRequest&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating objects
&lt;/h2&gt;

&lt;p&gt;To update a &lt;code&gt;NSManagedObject&lt;/code&gt; you will need to have the &lt;code&gt;NSManagedObject&lt;/code&gt; to update, fetched as described before and update its properties. And then save the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newText&lt;/span&gt;
&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newFolder&lt;/span&gt;
&lt;span class="nf"&gt;saveContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deleting objects
&lt;/h2&gt;

&lt;p&gt;To delete a &lt;code&gt;NSManagedObject&lt;/code&gt; you will need to have the &lt;code&gt;NSManagedObject&lt;/code&gt; to update, fetched as described before and delete it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;viewContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;I didn't explained every single CRUD method of CoreData like batch insertion and deletion since this guide is focused on the interaction between CoreData and SwiftUI. Every &lt;code&gt;NSManagedObjectContext&lt;/code&gt; method, background context, performAndAwait, … behaves exactly like it does with UIKit.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's all I have discovered so far about &lt;strong&gt;CoreData&lt;/strong&gt; used with &lt;strong&gt;SwiftUI&lt;/strong&gt;. This guide will be constantly updated.&lt;br&gt;
If you want to suggest a better way of doing something, &lt;strong&gt;leave a comment&lt;/strong&gt; and I will update this guide with the best option.&lt;br&gt;
I hope I helped you with you journey with SwiftUI and iOS development.&lt;br&gt;
See you in the next guide!&lt;/p&gt;




&lt;p&gt;If you would like to support my work and see this guide in action check out &lt;a href="https://apps.apple.com/us/app/braindump-notes-writing/id6448230631"&gt;BrainDump - Notes &amp;amp; Writing&lt;/a&gt;&lt;br&gt;
Thank you 🙏&lt;/p&gt;




&lt;h2&gt;
  
  
  SwiftyLion
&lt;/h2&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://blog.leonifrancesco.com/articles/coredata-with-swiftui"&gt;&lt;strong&gt;SwiftyLion&lt;/strong&gt;&lt;/a&gt;. Head over there if you like this post and want to read others like it.&lt;/p&gt;

</description>
      <category>swift</category>
      <category>swiftui</category>
      <category>coredata</category>
      <category>ios</category>
    </item>
  </channel>
</rss>
