<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Swift Archives - Forest and the Trees</title>
	<atom:link href="https://www.forestandthetrees.com/tag/swift/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.forestandthetrees.com/tag/swift/</link>
	<description>iOS Development</description>
	<lastBuildDate>Mon, 20 Mar 2023 14:19:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.1</generator>

<image>
	<url>https://www.forestandthetrees.com/wp-content/uploads/2021/11/cropped-fatt-32x32.png</url>
	<title>Swift Archives - Forest and the Trees</title>
	<link>https://www.forestandthetrees.com/tag/swift/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Troubleshooting apple-app-site-association file</title>
		<link>https://www.forestandthetrees.com/ios/troubleshooting-apple-app-site-association-file/</link>
					<comments>https://www.forestandthetrees.com/ios/troubleshooting-apple-app-site-association-file/#comments</comments>
		
		<dc:creator><![CDATA[Doug Marttila]]></dc:creator>
		<pubDate>Mon, 20 Mar 2023 14:19:54 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[deepLinking]]></category>
		<category><![CDATA[Swift]]></category>
		<category><![CDATA[universalLinking]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">https://www.forestandthetrees.com/?p=202</guid>

					<description><![CDATA[<p>Troubleshooting guides If the validator returns an error, curl the file From that thread&#8230; first thing to try is: add this end of the .htaccess file: Header set Content-type "application/pkcs7-mime" At Arcascope, we got it to work by adding this to .htaccess within /.well-known RewriteEngine On RewriteBase /.well-known/ # iOS RewriteRule ^apple-app-site-association$ apple-app-site-association.json [NC,L]</p>
<p>The post <a rel="nofollow" href="https://www.forestandthetrees.com/ios/troubleshooting-apple-app-site-association-file/">Troubleshooting apple-app-site-association file</a> appeared first on <a rel="nofollow" href="https://www.forestandthetrees.com">Forest and the Trees</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Troubleshooting guides</p>



<ul>
<li><a href="https://developer.apple.com/library/archive/qa/qa1916/_index.html">Apple troubleshooting guide</a></li>



<li><a href="https://stackoverflow.com/questions/39115167/universal-link-the-domain-has-some-validation-issue">Stackoverflow useful</a></li>



<li><a href="https://stackoverflow.com/questions/63524632/400-error-code-with-apple-app-site-association-json-file">Stackoverflow getting error in validator</a></li>
</ul>



<p>If the validator returns an error, <code>curl</code> the file</p>



<ul>
<li>In Terminal, <code>curl -i <a href="https://arcascope.com/apple-app-site-association" target="_blank" rel="noreferrer noopener">https://arcascope.com/apple-app-site-association</a></code> </li>



<li>You should see: <code>content-type: application/json</code> </li>



<li>If there’s no content-type for your aasa, <a href="https://stackoverflow.com/questions/40725154/how-to-set-correct-content-type-for-apple-app-site-association-file-on-nginx-rai">this thread</a> is very helpful</li>
</ul>



<p>From that thread&#8230; first thing to try is: add this end of the <code>.htaccess</code> file: <code>Header set Content-type "application/pkcs7-mime"</code></p>



<p>At Arcascope, we got it to work by adding this to .htaccess within /.well-known</p>



<pre class="wp-block-preformatted">RewriteEngine On
RewriteBase /.well-known/

# iOS
RewriteRule ^apple-app-site-association$ apple-app-site-association.json [NC,L]
</pre>
<p>The post <a rel="nofollow" href="https://www.forestandthetrees.com/ios/troubleshooting-apple-app-site-association-file/">Troubleshooting apple-app-site-association file</a> appeared first on <a rel="nofollow" href="https://www.forestandthetrees.com">Forest and the Trees</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.forestandthetrees.com/ios/troubleshooting-apple-app-site-association-file/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Universal Linking</title>
		<link>https://www.forestandthetrees.com/ios/universal-linking/</link>
					<comments>https://www.forestandthetrees.com/ios/universal-linking/#respond</comments>
		
		<dc:creator><![CDATA[Doug Marttila]]></dc:creator>
		<pubDate>Mon, 20 Mar 2023 14:19:22 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Swift]]></category>
		<category><![CDATA[universalLinking]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">https://www.forestandthetrees.com/?p=197</guid>

					<description><![CDATA[<p>At Arcascope, we implemented universal/deep linking in Shift: The App for Shift Work. The nice people at Arcascope were kind enough to let me publish this doc I wrote about it. Universal linking allows url links to open an iOS app instead of opening the url in Safari. Here are a few tutorials: Apple guide, [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.forestandthetrees.com/ios/universal-linking/">Universal Linking</a> appeared first on <a rel="nofollow" href="https://www.forestandthetrees.com">Forest and the Trees</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>At <a href="https://arcascope.com/">Arcascope</a>, we implemented universal/deep linking in <a href="Shift: The App for Shift Work">Shift: The App for Shift Work</a>. The nice people at Arcascope were kind enough to let me publish this doc I wrote about it. </p>



<p>Universal linking allows url links to open an iOS app instead of opening the url in Safari.</p>



<p>Here are a few tutorials: <a href="https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content?language=objc">Apple guide</a>, <a href="https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html#//apple_ref/doc/uid/TP40016308-CH12-SW1">older Apple guide</a>, <a href="https://www.kodeco.com/6080-universal-links-make-the-connection">Kodeco</a>. </p>



<h3>Step 1: Create an apple-app-site-association file</h3>



<ul>
<li>These are all over the internet: <a href="https://squareup.com/apple-app-site-association">Square,</a> <a href="https://drizly.com/apple-app-site-association">Drizly,</a> <a href="https://alltrails.com/apple-app-site-association">Alltrails,</a> <a href="https://arcascope.com/apple-app-site-association">Arcascope,</a> <a href="https://www.apple.com/.well-known/apple-app-site-association">Apple</a></li>



<li>There is an <a href="https://branch.io/resources/aasa-validator/">aasa validator</a> which can be used to check the validity of your site&#8217;s aasa</li>



<li>Aasas can be stored in root or in .well-known/ ← see Apple’s</li>



<li>While the file cannot have a json suffix, it has to be of type json. To do that set the .htaccess file to..</li>
</ul>



<pre class="wp-block-preformatted">&lt;Files apple-app-site-association&gt;
ForceType application/json
&lt;/Files&gt;
</pre>



<ul>
<li><a href="https://developer.apple.com/documentation/Xcode/supporting-associated-domains?language=objc">Apple’s documentation on creating the aasa file is helpful</a>.</li>



<li>Probably easiest to set <code>“paths”: [”*”]</code> initially (that will make all paths to your site open the app &#8211; more on this later)</li>



<li>If your aasa file is not validating, <a href="https://www.forestandthetrees.com/ios/troubleshooting-apple-app-site-association-file/">here are some troubleshooting tips</a>.</li>
</ul>



<h3>Step 2: <strong>Add the associated domains entitlement to your app</strong></h3>



<ul>
<li><a href="https://developer.apple.com/documentation/Xcode/supporting-associated-domains?language=objc">Apple’s documentation on doing this is helpful. (Scroll down to find the info)</a></li>



<li>Adding entitlements to the info.plist can be wonky. I ended up editing the entitlements file by hand. (<code>yourApp.entitlements</code>)</li>



<li>At this point, make a build to your device or a sim. If you go to Safari and enter the url of the associated domain, you should go to the app. </li>
</ul>



<h3>Step 3: Setting the paths</h3>



<ul>
<li>If you want the device to only go to your app for some urls, you need to edit the paths in apple-app-site-association file.</li>



<li>The paths param specifies which url should open the app.</li>



<li>The path must be a valid url. It needs to be visitable by a browser.</li>



<li>Test, now you should only go to the app if you enter a url listed in paths.</li>
</ul>



<h3>Step 4: Deep linking</h3>



<ul>
<li>By appending a query string to the url specified in <code>paths</code>, the app can retrieve the query string values and send the user to a specific part of the app.</li>



<li><a href="https://developer.apple.com/ios/universal-links/">The Apple documentation</a> on this is misleading as it only mentions modifying <code>AppDelegate</code>. If your app is in  SwiftUI, it listen for events on top-level ContentView.</li>
</ul>



<pre class="wp-block-preformatted">ContentView()
.onOpenURL {url in
	appState.handleUniversalLink(url: url)
}
</pre>



<ul>
<li>Once you have that working, it’s pretty easy to get the query params using URL and URLComponents. E.g. something like&#8230;</li>
</ul>



<pre class="wp-block-preformatted">public func handleUniversalLink (url: URL) {
&nbsp; &nbsp; let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)
&nbsp; &nbsp; let queryItems = urlComponents?.queryItems
&nbsp; &nbsp; guard let tabName = queryItems?.first(where: { $0.name == "tab" })?.value
&nbsp; &nbsp; tabState.currentState = tabName
&nbsp; }</pre>



<p>In the above case, the url the user would tap would be something like: <code>mydomain.com/thePathSpecifiedInTheAASAFile?tab=home</code></p>



<h3>What about non-Safari browsers?</h3>



<ul>
<li>Afaict, universal linking only works for Safari unless you want to spend money for <a href="https://www.branch.io/">Branch</a> or do a bunch of work with <a href="https://firebase.google.com/docs/dynamic-links">Firebase Dynamic Links</a>. (Here&#8217;s a <a href="https://github.com/ionic-team/capacitor/discussions/4368">link</a> discussing using dynamic links &#8211; I have not tried the suggestions)</li>



<li>None of the following apps open the app from Chrome or Firefox (iPhone running iOS16): Resy, Drizly, Amazon, or 1Password.</li>



<li>I think the best solution is how Drizly does it, which is to put a link that reads &#8220;Open the app&#8221; on an html page listed in <code>paths</code> (e.g., myUniversalLinkPage.html). And that link goes to the same page (e.g. myUniversalLinkPage.html). If the user taps that link, the app will open. For whatever reason, that seems to work.</li>
</ul>



<p>Finally, as part of figuring this out, it seems like Apple may eventually require apple-app-site-association files to be located in /.well-known</p>



<p>Again thanks to <a href="https://arcascope.com/">Arcascope</a> for letting me publish this.</p>
<p>The post <a rel="nofollow" href="https://www.forestandthetrees.com/ios/universal-linking/">Universal Linking</a> appeared first on <a rel="nofollow" href="https://www.forestandthetrees.com">Forest and the Trees</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.forestandthetrees.com/ios/universal-linking/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Asset Colors in Packages</title>
		<link>https://www.forestandthetrees.com/ios/asset-colors-in-packages/</link>
					<comments>https://www.forestandthetrees.com/ios/asset-colors-in-packages/#comments</comments>
		
		<dc:creator><![CDATA[Doug Marttila]]></dc:creator>
		<pubDate>Sun, 02 Jan 2022 22:53:41 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[Swift]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">https://www.forestandthetrees.com/?p=131</guid>

					<description><![CDATA[<p>Xcode allows you to easily add custom colors to the Assets file in your project. Add a Color Set, then use the Inspector to modify the color. To use your new color in your project, adding a color extension with the custom color&#8217;s name makes your life easier. Example below&#8230; Then you can do things [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.forestandthetrees.com/ios/asset-colors-in-packages/">Asset Colors in Packages</a> appeared first on <a rel="nofollow" href="https://www.forestandthetrees.com">Forest and the Trees</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Xcode allows you to easily add custom colors to the Assets file in your project. Add a Color Set, then use the Inspector to modify the color. </p>



<p>To use your new color in your project, adding a color extension with the custom color&#8217;s name makes your life easier. Example below&#8230;</p>



<pre class="wp-block-code"><code lang="swift" class="language-swift">extension Color {
    static let myAwesomeClr = Color("theNameOfMyColorInAssets")
}</code></pre>



<p>Then you can do things like&#8230;</p>



<pre class="wp-block-code"><code lang="swift" class="language-swift">Color(.myAwesomeClr)</code></pre>



<p>If you want to include that color in a Package, you need to..</p>



<ul><li>Declare your extension public (like everything in a Package) </li><li>Create a UIColor and cast that as a Color. (This took me a while to figure out which is why I am posting this.) See below&#8230;</li></ul>



<pre class="wp-block-code"><code lang="swift" class="language-swift">public extension Color {
    static let <meta charset="utf-8">myAwesomeClr = Color(UIColor(named: "<meta charset="utf-8">theNameOfMyColorInAssets", in: .module, compatibleWith: nil)!)
}</code></pre>



<ul><li>And, you need to add a resource target to your Package file&#8230;</li></ul>



<pre class="wp-block-code"><code lang="swift" class="language-swift">let package = Package(
    name: "YourPackageName",
    
... some common package info here omitted for this example ....

    targets: [
        .target(
            name: "YourPackageName",
            dependencies: [],
            resources: [
                .process("Assets.xcassets"),
            ]
            ),
        .testTarget(
...  more code here ....
</code></pre>



<p>Where Assets is the name of the media file that has your color.</p>
<p>The post <a rel="nofollow" href="https://www.forestandthetrees.com/ios/asset-colors-in-packages/">Asset Colors in Packages</a> appeared first on <a rel="nofollow" href="https://www.forestandthetrees.com">Forest and the Trees</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.forestandthetrees.com/ios/asset-colors-in-packages/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Dynamic Alert Package for iOS 13 &#8211; 14</title>
		<link>https://www.forestandthetrees.com/uncategorized/dynamic-alert-package-for-ios-13-14/</link>
					<comments>https://www.forestandthetrees.com/uncategorized/dynamic-alert-package-for-ios-13-14/#respond</comments>
		
		<dc:creator><![CDATA[Doug Marttila]]></dc:creator>
		<pubDate>Mon, 27 Dec 2021 19:36:37 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[Swift]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">https://www.forestandthetrees.com/?p=115</guid>

					<description><![CDATA[<p>If you need to create a simple alert popup, read Paul Hudson&#8217;s post. (The post also covers how to create alerts in the newer, iOS-15 way.) I needed a way for a single view to show alerts with one button, with two buttons, and with two buttons and a destructive action (destructive actions are shown [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://www.forestandthetrees.com/uncategorized/dynamic-alert-package-for-ios-13-14/">Dynamic Alert Package for iOS 13 &#8211; 14</a> appeared first on <a rel="nofollow" href="https://www.forestandthetrees.com">Forest and the Trees</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>If you need to create a simple alert popup, <a href="https://www.hackingwithswift.com/quick-start/swiftui/how-to-show-an-alert" data-type="URL" data-id="https://www.hackingwithswift.com/quick-start/swiftui/how-to-show-an-alert">read Paul Hudson&#8217;s post</a>. (The post also covers how to create alerts in the newer, iOS-15 way.)</p>



<p>I needed a way for a single view to show alerts with one button, with two buttons, and with two buttons and a destructive action (destructive actions are shown in red). I came up with a solution for <a href="https://www.forestandthetrees.com/fasty-mcfastface/" data-type="URL" data-id="https://www.forestandthetrees.com/fasty-mcfastface/">Fasty</a>, then I wanted to use it in another project, <a href="https://github.com/dmarttila/AlertPopUp-iOS13" data-type="URL" data-id="https://github.com/dmarttila/AlertPopUp-iOS13">so I put it in a package.</a></p>



<p>To use:</p>



<ol><li>Import the package</li><li>Add &#8220;@State private var alertParams: AlertParams?&#8221; to the view that you want to have the Alert.</li><li>At the bottom of that view, add: &#8220;.modifier(AlertModifier(alertParams: $alertParams))&#8221;</li><li>Add the following (or something similar) to the view: Button(&#8220;Pop up an alert with one button and an action&#8221;) { alertParams = AlertParams(title: &#8220;One Button&#8221;, message: &#8220;One button that calls an action&#8221;, primaryButtonLabel: &#8220;The button label&#8221;) { print(&#8220;The user clicked the Alert button&#8221;) } }</li></ol>



<pre class="wp-block-code"><code lang="swift" class="language-swift line-numbers">import SwiftUI
import AlertPopUp_iOS13

struct ContentView: View {
    @State private var alertParams: AlertParams?
    
    var body: some View {
        VStack {
            Button("Pop up an alert with one button and an action") {
                alertParams = AlertParams(title: "One Button", message: "One button that calls an action", primaryButtonLabel: "The button label") { print("The user clicked the Alert button") }
            }
        }
        .modifier(AlertModifier(alertParams: $alertParams))
        .padding()
    }
}</code></pre>



<p>The <a href="https://github.com/dmarttila/AlertPopUp-iOS13#readme">readMe</a> gives more details. </p>



<p><a href="https://github.com/dmarttila/AlertPopupsUsingPackage">Here&#8217;s a sample project that uses the package.</a></p>



<p></p>
<p>The post <a rel="nofollow" href="https://www.forestandthetrees.com/uncategorized/dynamic-alert-package-for-ios-13-14/">Dynamic Alert Package for iOS 13 &#8211; 14</a> appeared first on <a rel="nofollow" href="https://www.forestandthetrees.com">Forest and the Trees</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.forestandthetrees.com/uncategorized/dynamic-alert-package-for-ios-13-14/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
