Jekyll2023-07-26T08:25:47+00:00https://myswift.tips/feed.xmlDamian’s brief Swift TipsMeandering towards Swift from C#doesn’t have a target for net7.0-ios ios-arm642023-07-26T08:25:13+00:002023-07-26T08:25:13+00:00https://myswift.tips/2023/07/26/doesn't-have-a-target-for-net7.0-ios-ios-arm64<p>If you get this error:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/local/share/dotnet/sdk/7.0.306/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(5,5):
Error NETSDK1047: Assets file ‘/…/obj/project.assets.json' doesn't have a target for 'net7.0-ios/ios-arm64'.
Ensure that restore has run and that you have included 'net7.0-ios' in the TargetFrameworks
for your project.
You may also need to include 'ios-arm64' in your project's RuntimeIdentifiers. (NETSDK1047) (…)
</code></pre></div></div>
<p>In Visual Studio open the command prompt and enter</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dotnet restore <span class="nt">-r</span> ios-arm64
</code></pre></div></div>
<p>From <a href="https://github.com/xamarin/xamarin-macios/issues/14753#issuecomment-1105360239">https://github.com/xamarin/xamarin-macios/issues/14753#issuecomment-1105360239</a></p>If you get this error:If your C++ files are not compiling when adding them to Xcode2023-06-12T14:30:54+00:002023-06-12T14:30:54+00:00https://myswift.tips/2023/06/12/if-your-c++-files-are-not-compiling-when-adding-them-to-xcode<p>Check that when you import the containing folder you select <code class="language-plaintext highlighter-rouge">Create groups</code> rather than <code class="language-plaintext highlighter-rouge">Create folder references</code> in the import dialog</p>Check that when you import the containing folder you select Create groups rather than Create folder references in the import dialogUsing C++ from Swift in Xcode 15 beta One2023-06-12T13:24:55+00:002023-06-12T13:24:55+00:00https://myswift.tips/2023/06/12/using-c++-from-swift-in-xcode-15-beta-one<p>Make sure you don’t have <code class="language-plaintext highlighter-rouge">objective-c</code> and <code class="language-plaintext highlighter-rouge">objective-c++</code> selected under <code class="language-plaintext highlighter-rouge">Build-Settings Apple-Clang Module Verifier - Options for the C++ framework</code> - just <code class="language-plaintext highlighter-rouge">objective-c++</code></p>
<p>Also ensure your C++ “.hpp” file is set to <code class="language-plaintext highlighter-rouge">publc</code> in the target membership for the file properties if you can’t <code class="language-plaintext highlighter-rouge">#import</code> with an error <code class="language-plaintext highlighter-rouge">file not found</code></p>Make sure you don’t have objective-c and objective-c++ selected under Build-Settings Apple-Clang Module Verifier - Options for the C++ framework - just objective-c++When I archive a project in Xcode it shows the wrong version. Why might that be?2023-06-05T12:35:22+00:002023-06-05T12:35:22+00:00https://myswift.tips/2023/06/05/when-i-archive-a-project-in-xcode--it-shows-the-wrong-version.--why-might-that-be<p>Answer <a href="https://stackoverflow.com/a/75624890/3390">here</a></p>
<p><code class="language-plaintext highlighter-rouge">For a watch-only app, select the iOS target and update the value in Build Settings -> Versioning -> Marketing Version.</code></p>Answer hereUsing a Toggle in a MenuBar app2023-04-09T11:15:06+00:002023-04-09T11:15:06+00:00https://myswift.tips/2023/04/09/using-a-toggle-in-a-menubar-app-<p>Also launching an app on system startup</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">SwiftUI</span>
<span class="kd">import</span> <span class="kt">ServiceManagement</span>
<span class="kd">import</span> <span class="kt">Combine</span>
<span class="kd">@main</span>
<span class="kd">struct</span> <span class="kt">WatchControl_MacApp</span><span class="p">:</span> <span class="kt">App</span> <span class="p">{</span>
<span class="kd">@ObservedObject</span> <span class="k">var</span> <span class="nv">menuState</span> <span class="o">=</span> <span class="kt">LaunchOnStartupState</span><span class="o">.</span><span class="n">shared</span>
<span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">Scene</span> <span class="p">{</span>
<span class="kt">MenuBarExtra</span><span class="p">(</span><span class="s">"WatchControl"</span><span class="p">,</span> <span class="nv">image</span><span class="p">:</span> <span class="s">"Image"</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">Toggle</span><span class="p">(</span><span class="nv">isOn</span><span class="p">:</span> <span class="err">$</span><span class="n">menuState</span><span class="o">.</span><span class="n">launchOnLogin</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">Text</span><span class="p">(</span><span class="s">"Launch on startup"</span><span class="p">)</span>
<span class="p">}</span>
<span class="o">.</span><span class="nf">toggleStyle</span><span class="p">(</span><span class="o">.</span><span class="n">checkbox</span><span class="p">)</span>
<span class="kt">Divider</span><span class="p">()</span>
<span class="kt">Button</span><span class="p">(</span><span class="s">"Quit"</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">NSApplication</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">terminate</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span>
<span class="p">}</span><span class="o">.</span><span class="nf">keyboardShortcut</span><span class="p">(</span><span class="s">"q"</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">class</span> <span class="kt">LaunchOnStartupState</span> <span class="p">:</span> <span class="kt">ObservableObject</span> <span class="p">{</span>
<span class="kd">static</span> <span class="k">var</span> <span class="nv">shared</span> <span class="o">=</span> <span class="kt">LaunchOnStartupState</span><span class="p">()</span>
<span class="kd">@Published</span> <span class="k">var</span> <span class="nv">launchOnLogin</span> <span class="o">=</span> <span class="kt">SMAppService</span><span class="o">.</span><span class="n">mainApp</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="o">.</span><span class="n">enabled</span>
<span class="k">var</span> <span class="nv">cancelable</span><span class="p">:</span> <span class="kt">AnyCancellable</span><span class="p">?</span>
<span class="kd">private</span> <span class="nf">init</span><span class="p">()</span> <span class="p">{</span>
<span class="n">cancelable</span> <span class="o">=</span> <span class="err">$</span><span class="n">launchOnLogin</span><span class="o">.</span><span class="n">sink</span> <span class="p">{</span> <span class="n">newValue</span> <span class="k">in</span>
<span class="k">do</span> <span class="p">{</span>
<span class="k">if</span> <span class="n">newValue</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="err">“</span><span class="kt">Calling</span> <span class="kt">SMAppService</span><span class="o">.</span><span class="n">mainApp</span><span class="o">.</span><span class="nf">register</span><span class="p">()</span><span class="s">")
try SMAppService.mainApp.register()
} else {
print(“Calling SMAppService.mainApp.unregister()"</span><span class="p">)</span>
<span class="k">try</span> <span class="kt">SMAppService</span><span class="o">.</span><span class="n">mainApp</span><span class="o">.</span><span class="nf">unregister</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="err">“</span><span class="kt">Error</span> <span class="p">\(</span><span class="n">newValue</span> <span class="p">?</span> <span class="s">""</span> <span class="p">:</span> <span class="s">"un"</span><span class="p">)</span><span class="n">registering</span> <span class="k">for</span> <span class="nv">startup</span><span class="p">:</span> <span class="p">\(</span><span class="n">error</span><span class="p">)</span><span class="s">")
}
}
}
}
</span></code></pre></div></div>Also launching an app on system startupEncrypting and decrypting using a symetric key2023-04-09T11:08:59+00:002023-04-09T11:08:59+00:00https://myswift.tips/2023/04/09/encrypting-and-decrypting-using-a-symetric-key<p>Largely generated from ChatGPT</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">Foundation</span>
<span class="kd">import</span> <span class="kt">CommonCrypto</span>
<span class="kd">class</span> <span class="kt">CryptUtils</span> <span class="p">{</span>
<span class="kd">static</span> <span class="kd">func</span> <span class="nf">encrypt</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="o">-></span> <span class="kt">Data</span><span class="p">?</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">keyLength</span> <span class="o">=</span> <span class="n">kCCKeySizeAES128</span>
<span class="k">let</span> <span class="nv">keyData</span> <span class="o">=</span> <span class="nf">paddedKeyData</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">,</span> <span class="nv">keyLength</span><span class="p">:</span> <span class="n">keyLength</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">bufferSize</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">count</span> <span class="o">+</span> <span class="n">kCCBlockSizeAES128</span>
<span class="k">var</span> <span class="nv">buffer</span> <span class="o">=</span> <span class="kt">Data</span><span class="p">(</span><span class="nv">count</span><span class="p">:</span> <span class="n">bufferSize</span><span class="p">)</span>
<span class="k">var</span> <span class="nv">numBytesEncrypted</span><span class="p">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">let</span> <span class="nv">cryptStatus</span> <span class="o">=</span> <span class="n">keyData</span><span class="o">.</span><span class="n">withUnsafeBytes</span> <span class="p">{</span> <span class="n">keyBytes</span> <span class="o">-></span> <span class="kt">CCCryptorStatus</span> <span class="k">in</span>
<span class="n">data</span><span class="o">.</span><span class="n">withUnsafeBytes</span> <span class="p">{</span> <span class="n">dataBytes</span> <span class="o">-></span> <span class="kt">CCCryptorStatus</span> <span class="k">in</span>
<span class="n">buffer</span><span class="o">.</span><span class="n">withUnsafeMutableBytes</span> <span class="p">{</span> <span class="n">bufferBytes</span> <span class="o">-></span> <span class="kt">CCCryptorStatus</span> <span class="k">in</span>
<span class="k">return</span> <span class="kt">CCCrypt</span><span class="p">(</span>
<span class="kt">CCOperation</span><span class="p">(</span><span class="n">kCCEncrypt</span><span class="p">),</span>
<span class="kt">CCAlgorithm</span><span class="p">(</span><span class="n">kCCAlgorithmAES</span><span class="p">),</span>
<span class="kt">CCOptions</span><span class="p">(</span><span class="n">kCCOptionPKCS7Padding</span><span class="p">),</span>
<span class="n">keyBytes</span><span class="o">.</span><span class="n">baseAddress</span><span class="p">,</span>
<span class="n">keyLength</span><span class="p">,</span>
<span class="kc">nil</span><span class="p">,</span> <span class="c1">// Use ECB mode (no Initialization Vector)</span>
<span class="n">dataBytes</span><span class="o">.</span><span class="n">baseAddress</span><span class="p">,</span>
<span class="n">data</span><span class="o">.</span><span class="n">count</span><span class="p">,</span>
<span class="n">bufferBytes</span><span class="o">.</span><span class="n">baseAddress</span><span class="p">,</span>
<span class="n">bufferSize</span><span class="p">,</span>
<span class="o">&</span><span class="n">numBytesEncrypted</span>
<span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">if</span> <span class="n">cryptStatus</span> <span class="o">==</span> <span class="n">kCCSuccess</span> <span class="p">{</span>
<span class="n">buffer</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="n">numBytesEncrypted</span>
<span class="k">return</span> <span class="n">buffer</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"Error: Failed to encrypt data"</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">static</span> <span class="kd">func</span> <span class="nf">decrypt</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="o">-></span> <span class="kt">Data</span><span class="p">?</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">keyLength</span> <span class="o">=</span> <span class="n">kCCKeySizeAES128</span>
<span class="k">let</span> <span class="nv">keyData</span> <span class="o">=</span> <span class="nf">paddedKeyData</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">,</span> <span class="nv">keyLength</span><span class="p">:</span> <span class="n">keyLength</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">bufferSize</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">count</span> <span class="o">+</span> <span class="n">kCCBlockSizeAES128</span>
<span class="k">var</span> <span class="nv">buffer</span> <span class="o">=</span> <span class="kt">Data</span><span class="p">(</span><span class="nv">count</span><span class="p">:</span> <span class="n">bufferSize</span><span class="p">)</span>
<span class="k">var</span> <span class="nv">numBytesDecrypted</span><span class="p">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">let</span> <span class="nv">cryptStatus</span> <span class="o">=</span> <span class="n">keyData</span><span class="o">.</span><span class="n">withUnsafeBytes</span> <span class="p">{</span> <span class="n">keyBytes</span> <span class="o">-></span> <span class="kt">CCCryptorStatus</span> <span class="k">in</span>
<span class="n">data</span><span class="o">.</span><span class="n">withUnsafeBytes</span> <span class="p">{</span> <span class="n">dataBytes</span> <span class="o">-></span> <span class="kt">CCCryptorStatus</span> <span class="k">in</span>
<span class="n">buffer</span><span class="o">.</span><span class="n">withUnsafeMutableBytes</span> <span class="p">{</span> <span class="n">bufferBytes</span> <span class="o">-></span> <span class="kt">CCCryptorStatus</span> <span class="k">in</span>
<span class="k">return</span> <span class="kt">CCCrypt</span><span class="p">(</span>
<span class="kt">CCOperation</span><span class="p">(</span><span class="n">kCCDecrypt</span><span class="p">),</span>
<span class="kt">CCAlgorithm</span><span class="p">(</span><span class="n">kCCAlgorithmAES</span><span class="p">),</span>
<span class="kt">CCOptions</span><span class="p">(</span><span class="n">kCCOptionPKCS7Padding</span><span class="p">),</span>
<span class="n">keyBytes</span><span class="o">.</span><span class="n">baseAddress</span><span class="p">,</span>
<span class="n">keyLength</span><span class="p">,</span>
<span class="kc">nil</span><span class="p">,</span> <span class="c1">// Use ECB mode (no Initialization Vector)</span>
<span class="n">dataBytes</span><span class="o">.</span><span class="n">baseAddress</span><span class="p">,</span>
<span class="n">data</span><span class="o">.</span><span class="n">count</span><span class="p">,</span>
<span class="n">bufferBytes</span><span class="o">.</span><span class="n">baseAddress</span><span class="p">,</span>
<span class="n">bufferSize</span><span class="p">,</span>
<span class="o">&</span><span class="n">numBytesDecrypted</span>
<span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">if</span> <span class="n">cryptStatus</span> <span class="o">==</span> <span class="n">kCCSuccess</span> <span class="p">{</span>
<span class="n">buffer</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="n">numBytesDecrypted</span>
<span class="k">return</span> <span class="n">buffer</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"Error: Failed to decrypt data"</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">func</span> <span class="nf">paddedKeyData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="nv">keyLength</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-></span> <span class="kt">Data</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">keyData</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">using</span><span class="p">:</span> <span class="o">.</span><span class="n">utf8</span><span class="p">)</span><span class="o">!</span>
<span class="k">let</span> <span class="nv">paddedKeyData</span> <span class="o">=</span> <span class="kt">NSMutableData</span><span class="p">(</span><span class="nv">length</span><span class="p">:</span> <span class="n">keyLength</span><span class="p">)</span><span class="o">!</span>
<span class="n">keyData</span><span class="o">.</span><span class="n">withUnsafeBytes</span> <span class="p">{</span> <span class="p">(</span><span class="nv">keyBytes</span><span class="p">:</span> <span class="kt">UnsafeRawBufferPointer</span><span class="p">)</span> <span class="k">in</span>
<span class="k">if</span> <span class="k">let</span> <span class="nv">baseAddress</span> <span class="o">=</span> <span class="n">keyBytes</span><span class="o">.</span><span class="n">baseAddress</span> <span class="p">{</span>
<span class="n">paddedKeyData</span><span class="o">.</span><span class="nf">replaceBytes</span><span class="p">(</span><span class="nv">in</span><span class="p">:</span> <span class="kt">NSRange</span><span class="p">(</span><span class="nv">location</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">length</span><span class="p">:</span> <span class="nf">min</span><span class="p">(</span><span class="n">keyData</span><span class="o">.</span><span class="n">count</span><span class="p">,</span> <span class="n">keyLength</span><span class="p">)),</span> <span class="nv">withBytes</span><span class="p">:</span> <span class="n">baseAddress</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">paddedKeyData</span> <span class="k">as</span> <span class="kt">Data</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>Largely generated from ChatGPTDisplaying a SwiftUI view from a MenuBar only app2023-04-09T11:01:56+00:002023-04-09T11:01:56+00:00https://myswift.tips/2023/04/09/displaying-a-swiftui-view-from-a-menubar-only-app<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">AppKit</span>
<span class="kd">import</span> <span class="kt">SwiftUI</span>
<span class="kd">struct</span> <span class="kt">MyAlertView</span><span class="p">:</span> <span class="kt">View</span> <span class="p">{</span>
<span class="k">var</span> <span class="nv">body</span><span class="p">:</span> <span class="kd">some</span> <span class="kt">View</span> <span class="p">{</span>
<span class="kt">VStack</span> <span class="p">{</span>
<span class="kt">Text</span><span class="p">(</span><span class="s">"This is a SwiftUI view in an alert."</span><span class="p">)</span>
<span class="kt">Button</span><span class="p">(</span><span class="s">"OK"</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Handle button action</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">.</span><span class="nf">frame</span><span class="p">(</span><span class="nv">width</span><span class="p">:</span> <span class="mi">300</span><span class="p">,</span> <span class="nv">height</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">activateApp</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">myApp</span> <span class="o">=</span> <span class="kt">NSRunningApplication</span><span class="o">.</span><span class="n">current</span>
<span class="n">myApp</span><span class="o">.</span><span class="nf">activate</span><span class="p">(</span><span class="nv">options</span><span class="p">:</span> <span class="o">.</span><span class="n">activateIgnoringOtherApps</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">showAlertWithSwiftUIView</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">panel</span> <span class="o">=</span> <span class="kt">NSPanel</span><span class="p">(</span><span class="nv">contentRect</span><span class="p">:</span> <span class="kt">NSRect</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">width</span><span class="p">:</span> <span class="mi">300</span><span class="p">,</span> <span class="nv">height</span><span class="p">:</span> <span class="mi">200</span><span class="p">),</span>
<span class="nv">styleMask</span><span class="p">:</span> <span class="p">[</span><span class="o">.</span><span class="n">titled</span><span class="p">,</span> <span class="o">.</span><span class="n">closable</span><span class="p">,</span> <span class="o">.</span><span class="n">fullSizeContentView</span><span class="p">],</span>
<span class="nv">backing</span><span class="p">:</span> <span class="o">.</span><span class="n">buffered</span><span class="p">,</span>
<span class="nv">defer</span><span class="p">:</span> <span class="kc">false</span><span class="p">)</span>
<span class="n">panel</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="s">"Alert"</span>
<span class="n">panel</span><span class="o">.</span><span class="nf">center</span><span class="p">()</span>
<span class="nf">activateApp</span><span class="p">()</span>
<span class="n">panel</span><span class="o">.</span><span class="nf">makeKeyAndOrderFront</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">hostingView</span> <span class="o">=</span> <span class="kt">NSHostingView</span><span class="p">(</span><span class="nv">rootView</span><span class="p">:</span> <span class="kt">MyAlertView</span><span class="p">(</span><span class="nv">isPresented</span><span class="p">:</span> <span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">get</span><span class="p">:</span> <span class="p">{</span>
<span class="n">panel</span><span class="o">.</span><span class="n">isVisible</span>
<span class="p">},</span> <span class="nv">set</span><span class="p">:</span> <span class="p">{</span> <span class="n">isVisible</span> <span class="k">in</span>
<span class="k">if</span> <span class="o">!</span><span class="n">isVisible</span> <span class="p">{</span>
<span class="n">panel</span><span class="o">.</span><span class="nf">orderOut</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">})))</span>
<span class="n">panel</span><span class="o">.</span><span class="n">contentView</span> <span class="o">=</span> <span class="n">hostingView</span>
<span class="p">}</span>
</code></pre></div></div>```swift import AppKit import SwiftUIIncluding changes in memory when querying core data2022-02-26T13:38:15+00:002022-02-26T13:38:15+00:00https://myswift.tips/2022/02/26/including-changes-in-memory-when-querying-core-data<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">context</span> <span class="o">=</span> <span class="kt">PersistenceController</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="n">container</span><span class="o">.</span><span class="n">viewContext</span>
<span class="k">return</span> <span class="k">try</span> <span class="n">context</span><span class="o">.</span><span class="n">performAndWait</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">fetchRequest</span> <span class="o">=</span> <span class="kt">DbResource</span><span class="o">.</span><span class="nf">fetchRequest</span><span class="p">()</span>
<span class="n">fetchRequest</span><span class="o">.</span><span class="n">includesPendingChanges</span> <span class="o">=</span> <span class="kc">true</span>
<span class="n">fetchRequest</span><span class="o">.</span><span class="n">predicate</span> <span class="o">=</span> <span class="kt">NSPredicate</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span> <span class="s">"bodyHash == %@"</span><span class="p">,</span> <span class="n">bodyHash</span><span class="p">)</span>
<span class="k">return</span> <span class="k">try</span> <span class="n">context</span><span class="o">.</span><span class="nf">fetch</span><span class="p">(</span><span class="n">fetchRequest</span><span class="p">)</span><span class="o">.</span><span class="n">first</span>
<span class="p">}</span>
</code></pre></div></div>let context = PersistenceController.shared.container.viewContext return try context.performAndWait { let fetchRequest = DbResource.fetchRequest() fetchRequest.includesPendingChanges = true fetchRequest.predicate = NSPredicate(format: "bodyHash == %@", bodyHash) return try context.fetch(fetchRequest).first }Extending an optional Double to convert it to an NSNumber2022-02-22T16:16:39+00:002022-02-22T16:16:39+00:00https://myswift.tips/2022/02/22/extending-an-optional-double-to-convert-it-to-an-nsnumber<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">Optional</span> <span class="k">where</span> <span class="kt">Wrapped</span> <span class="o">==</span> <span class="kt">Double</span> <span class="p">{</span>
<span class="k">var</span> <span class="nv">asNSNumber</span> <span class="p">:</span> <span class="kt">NSNumber</span><span class="p">?</span> <span class="p">{</span>
<span class="k">if</span> <span class="k">let</span> <span class="nv">val</span> <span class="o">=</span> <span class="k">self</span> <span class="p">{</span>
<span class="k">return</span> <span class="kt">NSNumber</span><span class="p">(</span><span class="nv">floatLiteral</span><span class="p">:</span> <span class="n">val</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>extension Optional where Wrapped == Double { var asNSNumber : NSNumber? { if let val = self { return NSNumber(floatLiteral: val) } else { return nil } } }Custom Error with localizedDescription2021-09-29T14:47:33+00:002021-09-29T14:47:33+00:00https://myswift.tips/2021/09/29/custom-error-with-localizeddescription<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">EncyptError</span><span class="p">:</span> <span class="kt">LocalizedError</span> <span class="p">{</span>
<span class="k">case</span> <span class="nf">error</span><span class="p">(</span><span class="kt">String</span><span class="p">)</span>
<span class="kd">public</span> <span class="k">var</span> <span class="nv">errorDescription</span><span class="p">:</span> <span class="kt">String</span><span class="p">?</span> <span class="p">{</span>
<span class="k">switch</span> <span class="k">self</span> <span class="p">{</span>
<span class="k">case</span> <span class="o">.</span><span class="nf">error</span><span class="p">(</span><span class="k">let</span> <span class="nv">message</span><span class="p">):</span>
<span class="k">return</span> <span class="n">message</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>enum EncyptError: LocalizedError { case error(String) public var errorDescription: String? { switch self { case .error(let message): return message } } }