<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Fady Derias on Medium]]></title>
        <description><![CDATA[Stories by Fady Derias on Medium]]></description>
        <link>https://medium.com/@fadiderias?source=rss-da92204bda7b------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*HC4xhkVZUrxUbPO-Rp-TwA.jpeg</url>
            <title>Stories by Fady Derias on Medium</title>
            <link>https://medium.com/@fadiderias?source=rss-da92204bda7b------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 29 Apr 2026 01:32:19 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@fadiderias/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[iOS Security Tutorial — Part 2]]></title>
            <link>https://medium.com/@fadiderias/ios-security-tutorial-part-2-c481036170ca?source=rss-da92204bda7b------2</link>
            <guid isPermaLink="false">https://medium.com/p/c481036170ca</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Fady Derias]]></dc:creator>
            <pubDate>Thu, 24 Oct 2019 15:55:56 GMT</pubDate>
            <atom:updated>2019-12-30T00:09:59.124Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>iOS Security Tutorial — Part 2</strong></h3><h4>Signature &amp; Verification + Secure Enclave</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aoUBQg-CVcd-fEEAi2sjgg.png" /><figcaption>Thanks to <a href="https://lukaszadam.com/illustrations">Lukas</a> for the illustration</figcaption></figure><p>A digital signature is a guarantee to the receiver regarding the authenticity, integrity, and verification of the sender. To simply put, it’s equivalent to a handwritten signature. A digital signature is achieved using a different key pair than the one used for encryption/decryption.</p><p>Digital signatures are utilized in many electronic aspects, Xcode does digitally sign your code whenever you’re to submit your app for testing or to the app store. In general, this is how a sender signs the data to be sent:-</p><ol><li>The sender encrypts his/her data with a specific hash algorithm (ex: sha256). The output of that hash algorithm is labelled as a “digest” (ex: 6e04f289)</li><li>The sender then <strong>encrypts the digest</strong> with his/her private key. The <strong>encrypted digest </strong>is known as the “<em>digital signature</em>” of the data.</li><li>The sender sends the <strong>original data</strong> + the <strong>encrypted digest</strong>. Notice that the encrypted digest is utilized only for verifying the sender but the message itself is not encrypted by the same private key utilized for signature and verification. It’s encrypted via the private key created as similar to the above section.</li></ol><p>This how a receiver verifies the received data:-</p><ol><li>The receiver receives the message alongside the digital signature.</li><li>The receiver <strong>decrypts</strong> the digital signature using the sender’s public key <br>-&gt; Output is the digest.</li><li>The receiver uses the same hashing algorithm similar to the one the sender used to hash the received plain data from the sender -&gt; This will output a digest.</li><li>If the output digest from step 2 (digital signature) = output digest from step 3 (hash of the received plain data) -&gt; The receiver can validate the integrity of the data.</li></ol><p>For this tutorial, the private key to be used for digital signature is to be stored in the secure enclave while the public key is to be stored outside of it and to be shared with the receiver.</p><p>The<a href="https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave"> secure enclave</a> based on Apple’s documentation is “a hardware-based key manager that’s isolated from the main processor to provide an extra layer of security. When you store a private key in the Secure Enclave, you never actually handle the key, making it difficult for the key to becoming compromised. Instead, you instruct the Secure Enclave to create the key, securely store it, and perform operations with it. You receive only the output of these operations, such as encrypted data or a cryptographic signature verification outcome.”</p><p>It’s important to point out that iOS’s secure enclave supports 256-bit elliptic curve keys (ECC) only. Notice that the private key inside the secure enclave can also be used for data encryption but that is limited to symmetric encryption using the eciesEncryptionCofactorX963SHA256AESGCM algorithm.</p><p>Let’s get coding.</p><p>The first thing to do is to generate a new key pair for signing and verification. The process is as similar to the last section, but with an extra step regarding setting the attributes for the private key. That is specifying what is known as an “Access Control”.</p><p>The access control object is what defines the mechanism to access the private key inside the secure enclave in order to sign data. One rule setting the accessibility level required when accessing the private key inside the secure enclave (ex: when the device is unlocked or when there’s a passcode set).</p><pre>//Creating the Access Control Object<br>let access =</pre><pre>SecAccessControlCreateWithFlags(kCFAllocatorDefault, <strong>//1</strong></pre><pre>kSecAttrAccessibleWhenUnlockedThisDeviceOnly, <strong>//2</strong></pre><pre>[.privateKeyUsage,.biometryAny], <strong>//3</strong></pre><pre>nil)! <strong>//4</strong></pre><p>The access object is created by invoking the <em>SecAccessControlCreateWithFlags</em> security API.</p><ol><li>The first parameter of the API is the allocator. Usually, this is set to the default allocator.</li><li>Afterwards, the level of protection required to access the private key inside the secure enclave. This is set to kSecAttrAccessibleWhenUnlockedThisDeviceOnly, which means that this item is to be only accessed on the device that created it and only when the device is unlocked.</li><li>An array of flags that are set to <strong>.privateKeyUsage</strong> which clearly defined that private key generated inside the secure enclave is to be used for signing and verification &amp; <strong>.biometryAny </strong>that instructs the system to make the key only available when the system can authenticate the user with any available biometric authentication.</li><li>Last is an error object to hold any error that might occur, but it’s ignored for now.</li></ol><p>Next step is to assemble the key pair attributes as done in the previous sections. First thing is to assemble the private key parameters dictionary (which will include the created access control object)</p><pre>let secEnclaveTag = secureEnclaveKeyTag.data(using: .utf8)! <strong>//1</strong><br>let privateKeyParams: [String: AnyObject] = [</pre><pre>kSecAttrIsPermanent as String: true as AnyObject, <strong>//2</strong></pre><pre>kSecAttrApplicationTag as String: secEnclaveTag as AnyObject, <strong>//3</strong></pre><pre>kSecAttrAccessControl as String: access <strong>//4</strong></pre><pre>]</pre><ol><li>Create a tag for the private key.</li><li><a href="https://developer.apple.com/documentation/security/ksecattrispermanent">kSecAttrIsPermanent</a>: A key whose value is a boolean. If true, it indicates that the cryptographic key should be stored in the default keychain at creation time.</li><li><a href="https://developer.apple.com/documentation/security/ksecattrapplicationtag">kSecAttrApplicationTag</a>: A key whose value is an attribute with a unique NSData value so that you can find and retrieve the private key later on from the key chain. It’s constructed from a string and preferable to be in reverse DNS notation.</li><li><a href="https://developer.apple.com/documentation/security/ksecattraccesscontrol">kSecAttrAccessControl</a>: access control object generated to indicate how the key can be used.</li></ol><p>Assemble the attributes dictionary that is to be utilized for generating the key pair as the last section.</p><pre>let attributes = [<br>kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, <strong>//1</strong></pre><pre>kSecAttrKeySizeInBits as String: 256, <strong>//2</strong></pre><pre>kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave, <strong>//3</strong></pre><pre>kSecPrivateKeyAttrs as String: privateKeyParams] as CFDictionary <strong>//4</strong></pre><ul><li><a href="https://developer.apple.com/documentation/security/ksecattrkeytype">kSecAttrKeyType</a>: A key whose value indicates the type of cryptography algorithm used to produce the key pair (public and private keys). Set to ECC (since the secure enclave supports only ECC keys)</li><li><a href="https://developer.apple.com/documentation/security/ksecattrkeysizeinbits">kSecAttrKeySizeInBits</a>: A key whose value indicates the size of the generated key pair. Set to 256 bits (since the secure enclave supports only 256-bit keys)</li><li>** <a href="https://developer.apple.com/documentation/security/ksecattrtokenid"><strong>kSecAttrTokenID</strong></a>: A key whose value is kSecAttrTokenIDSecureEnclave. This indicates that the generation operation for the private key should take place inside the Secure Enclave.</li><li><a href="https://developer.apple.com/documentation/security/ksecprivatekeyattrs">kSecPrivateKeyAttrs</a>: A key whose value is set to the created sub-dictionary that does contain the specifications of the private key of the pair (that includes the access control object)</li></ul><p>The last step is to generate the key pair using the attributes dictionary via the <em>SecKeyCreateRandomKey</em> API.</p><pre>var error: Unmanaged&lt;CFError&gt;?<br>guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &amp;error) else {</pre><pre>throw error!.takeRetainedValue() as Error</pre><pre>}</pre><p>The generated key is a reference to the private key stored inside the secure enclave. You can always obtain a reference to it, but can never inspect its data because it’s inside the secure enclave.</p><p>You can generate the public key afterwards from that reference of the private key that is to be distributed.</p><pre>guard let publicKey = SecKeyCopyPublicKey(privateKey) else {</pre><pre>print(“Public key generation error”)</pre><pre>return””</pre><pre>}</pre><p><strong>Digital Signature</strong></p><pre>let message = “4043 1710 2843 4577”</pre><pre>guard let messageData = message.data(using: String.Encoding.utf8) else {</pre><pre>print(“Invalid message to sign.”)</pre><pre>} <strong>//1</strong></pre><pre>guard let signData = SecKeyCreateSignature(</pre><pre>privateKey,</pre><pre>SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256,</pre><pre>messageData as CFData, nil) else {</pre><pre>print(“Signing Error”)</pre><pre>return nil</pre><pre>} <strong>//2</strong></pre><pre>let signedData = signData as Data</pre><pre>let signedString = signedData.base64EncodedString(options: [])</pre><pre>print(“Signed String”, signedString) <strong>//3</strong></pre><ol><li>Create/Retrieve the message required to sign and transform it into a Data object.</li><li>Sign the data via the <em>SecKeyCreateSignature</em> security API. It takes the following parameters</li></ol><ul><li>The created private key via the secure enclave</li><li>The hashing algorithm required for encryption (SecKeyAlgorithm).</li><li>The message Data object.</li></ul><p>3. In case you wanted to check the signed data, you can transform it to a Base 64 encoded string and print it.</p><p><strong>Verification</strong></p><pre>let message = “4043 1710 2843 4577”</pre><pre>guard let messageData = message.data(using: String.Encoding.utf8) else {</pre><pre>print(“ECC bad message to verify”)</pre><pre>return false</pre><pre>} <strong>//1</strong></pre><pre>guard let signedMessageData = signatureString.data(using: String.Encoding.utf8) else {</pre><pre>print(“Invalid message to verify.”)</pre><pre>} <strong>//2</strong></pre><pre>let verify = SecKeyVerifySignature(</pre><pre>publicKey,</pre><pre>SecKeyAlgorithm.ecdsaSignatureMessageX962SHA256,</pre><pre>messageData as CFData,</pre><pre>signatureData as CFData,</pre><pre>nil) <strong>//3</strong></pre><ol><li>Create/Retrieve the message required to sign and transform it into a Data object.</li><li>Get the signed string and transform it into “Data” object.</li><li>Verify the data via the <em>SecKeyVerifySignature</em> security API. It takes the following parameters</li></ol><ul><li>The created public key via the private key in the secure enclave.</li><li>The hashing algorithm (SecKeyAlgorithm) should be exactly the same as the one used for signing.</li><li>The message Data object.</li><li>The signature Data object.</li><li>Error object.</li></ul><p>The returned value is a boolean value that indicates whether the received data is verified or not.</p><p><strong>Summary</strong></p><p>In this tutorial you’ve learned:</p><ol><li>Symmetric vs Asymmetric Encryption &amp; Decryption.</li><li>How to apply Asymmetric Encryption in iOS apps using Swift Security APIs.</li><li>iOS Secure Element/Enclave.</li><li>Digital Signature and Verification.</li><li>How to digitally sign and verify data via the secure enclave.</li></ol><p><strong>References</strong></p><ol><li><a href="https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave">Storing Keys in Secure Enclave.</a></li><li><a href="https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/signing_and_verifying">Signing and Verifying.</a></li><li><a href="https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/generating_new_cryptographic_keys#2863927">Generating New Cryptographic Keys.</a></li><li><a href="https://www.linkedin.com/pulse/ios-10-how-use-secure-enclave-touch-id-protect-your-keys-satyam-tyagi">iOS 10: How to Use Secure Enclave and Touch ID to Protect your Keys</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c481036170ca" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[iOS Security Tutorial — Part 1]]></title>
            <link>https://medium.com/@fadiderias/ios-security-tutorial-part-1-6571172d912?source=rss-da92204bda7b------2</link>
            <guid isPermaLink="false">https://medium.com/p/6571172d912</guid>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Fady Derias]]></dc:creator>
            <pubDate>Thu, 24 Oct 2019 15:55:36 GMT</pubDate>
            <atom:updated>2019-12-30T00:13:48.407Z</atom:updated>
            <content:encoded><![CDATA[<h3>iOS Security Tutorial — Part 1</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nO4SpUaecjUsHUCH-28QfQ.png" /><figcaption>Thanks to <a href="https://www.drawkit.io/">drawkit.io</a> for the nice illustration</figcaption></figure><p>On March 25th 2019, Apple announced its new consumer U.S. credit card issued by Goldman Sachs “Apple Card”. They pointed out that for every Apple Card, there’s a unique per device card number that is created and stored safely in the device’s <strong>secure element</strong> &amp; that every purchase is authenticated with Touch ID or Face ID.</p><p>The purpose of this tutorial is to further elaborate what is the iOS device’s secure element Apple pointed out during their new Card announcement and how developers can utilize it for purposes that have to do with their applications.</p><p>First, let’s go through some base concepts to establish the purpose of this tutorial.</p><p><strong>Symmetric and Asymmetric</strong> <strong>Encryption</strong></p><p>Generally, encryption is some way to conceal messages between two parties to prevent unauthorized access to these messages. In other words, consider you’re sending a message to a friend and you don’t want an outsider to read that message, so you scramble it in some way that only both of you and your friend know how to read/decipher it.</p><p>One way to conceal that message is for the sender to add a password to it and provide the receiver with that password. This happens to be of certain threat because there’s a high chance that whatever method the sender uses to send the password to the receiver, it’s going to be compromised. This method is called <strong>Symmetric Encryption</strong> and proved to be inefficient and for that <strong>Asymmetric Encryption</strong> was introduced.</p><p>Asymmetric encryption mainly relies on<a href="https://www.cloudflare.com/learning/ssl/what-is-a-cryptographic-key/"> cryptographic keys</a>. “In cryptography, a key is a string of characters used within an encryption algorithm for altering data so that it appears random. Like a physical key, it locks (encrypts) data so that only someone with the right key can unlock (decrypt) it.”</p><p>In Asymmetric Encryption, both the sender and the receiver, have a key pair. That is a public key and a private key. Both parties share their public keys to one another and keep the private key only a secret to themselves. Whenever the sender (A) wants to send a message to the receiver (B), (A) encrypts the message using (B)’s public key, and for (B) to read the message, they have to decrypt the message using their very own secret private key.</p><p>A key pair can be generated using numerous cryptography algorithms (<a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)">RSA algorithm,</a><a href="https://en.wikipedia.org/wiki/Elliptic-curve_cryptography"> ECC algorithm</a> .. etc). As a result, both generated keys are linked together but still can’t be derived from each other.</p><h3>Asymmetric Encryption in Swift</h3><p>For asymmetric encryption in iOS, here are the requires steps :</p><ol><li>Create an attributes dictionary that would define the specifications of the asymmetric key pair to be generated. Specifications like the keys’ size in bits and the algorithm used to generate the pair. These specifications are defined via dedicated iOS Security “<a href="https://developer.apple.com/documentation/security/keychain_services/keychain_items/item_attribute_keys_and_values?language=objc">Key generation attributes</a>”.</li><li>Passing the attributes dictionary to a dedicated Swift API to generate both the public and private keys.</li><li>Encrypting a message using the public key.</li><li>Decrypting the message using the private key.</li></ol><p>Let’s get ourselves coding.</p><h4>Attributes Dictionary</h4><p>The attributes dictionary define properties for both the public and private keys. It’s done over two steps.</p><p>The first step is to create a Dictionary object that will act as a sub-dictionary in the main attributes dictionary. It defines the specifications of the private key.</p><pre>let privateKeyTag = “com.security.tutorial”.data(using: .utf8)!</pre><pre>let privateKeyParams: [String: Any] = [</pre><pre>kSecAttrCanDecrypt as String: true,</pre><pre>kSecAttrIsPermanent as String: true,</pre><pre>kSecAttrApplicationTag as String: privateKeyTag]</pre><ul><li><a href="https://developer.apple.com/documentation/security/ksecattrcandecrypt">kSecAttrCanDecrypt</a>: A key whose value indicates that the cryptographic private key can be used for decryption.</li><li><a href="https://developer.apple.com/documentation/security/ksecattrispermanent">kSecAttrIsPermanent</a>: A key whose value is a boolean. If true, it indicates that the cryptographic key should be stored in the default keychain at creation time.</li><li><a href="https://developer.apple.com/documentation/security/ksecattrapplicationtag">kSecAttrApplicationTag</a>: A key whose value is an attribute with a unique NSData value so that you can find and retrieve the private key later on from the key chain. It’s constructed from a string and preferable to be in reverse DNS notation.</li></ul><p>The second step is to create the main attributes dictionary object.</p><pre>let attributes = <br>[kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,</pre><pre>kSecAttrKeySizeInBits as String: 256,</pre><pre>kSecPrivateKeyAttrs as String:</pre><pre>privateKeyParams] as CFDictionary</pre><ul><li><a href="https://developer.apple.com/documentation/security/ksecattrkeytype">kSecAttrKeyType</a>: A key whose value indicates the type of cryptography algorithm used to produce the key pair (public and private keys). Set to elliptic curve algorithm (ECC).</li><li><a href="https://developer.apple.com/documentation/security/ksecattrkeysizeinbits">kSecAttrKeySizeInBits</a>: A key whose value indicates the size of the generated key pair. Set to 256 bits.</li><li><a href="https://developer.apple.com/documentation/security/ksecprivatekeyattrs">kSecPrivateKeyAttrs</a>: A key whose value is set to the created sub-dictionary that does contain the specifications of the private key.</li></ul><h4>2. Key Pair Generation</h4><p>The first thing to do is to create two variable objects of type <strong>“SecKey”</strong> to hold references to the generated key pair (public key and private key).</p><pre>//Variables to store both the public and private keys.<br>var publicKeySec, privateKeySec: SecKey?</pre><pre>Second thing is to call the SecKeyGeneratePair API to generate the public and private keys using the created attributes dictionary.</pre><pre>//Generating both the public and private keys via the SecGeneratePair APIs.</pre><pre>SecKeyGeneratePair(attributes, &amp;publicKeySec, &amp;privateKeySec)</pre><h4>3. Encryption</h4><p>Let’s assume the message to be encrypted is a credit card number string.</p><pre>let message = “4043 1710 2843 4577” <strong>//1</strong></pre><pre>guard let messageData = message.data(using: String.Encoding.utf8) else {</pre><pre>print(“Bad message to encrypt”)</pre><pre>} <strong>//2</strong></pre><pre>guard let encryptData = SecKeyCreateEncryptedData(</pre><pre>publicKey,</pre><pre>SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM,</pre><pre>messageData as CFData,</pre><pre>nil) else {</pre><pre>print(“Encryption Error”)</pre><pre>}</pre><p>The steps for generating an encrypted string are as follows:-</p><ol><li>Set/Get the message to be encrypted.</li><li>Set the message to be of type Data.</li><li>Utilize the SecKeyCreateEncryptedData security API to encrypt the message data. You pass public key and the encryption algorithm (SecKeyAlgorithm) for it to be utilized.</li></ol><h4>4. Decryption</h4><pre>guard let messageData = Data(base64Encoded: encryptedString, options: []) else {<br>print(“Bad message to decrypt”)</pre><pre>return nil</pre><pre>} <strong>//1</strong></pre><pre>guard let decryptData = SecKeyCreateDecryptedData(</pre><pre>privateKey,</pre><pre>SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM,</pre><pre>messageData as CFData,</pre><pre>nil) else {</pre><pre>print(“Decryption Error”)</pre><pre>return nil</pre><pre>} <strong>//2</strong></pre><pre>let decryptedData = decryptData as Data</pre><pre>guard</pre><pre>let decryptedString = String(data: decryptedData, encoding: String.Encoding.utf8) else {</pre><pre>print(“Error retrieving string”)</pre><pre>}</pre><p>The steps for decrypting an encrypted string are as follows:</p><ol><li>Get the encrypted message string &amp; transform the encrypted message to be of type Data.</li><li>Utilize the <strong><em>SecKeyCreateDecryptedData</em></strong> security API to decrypt the encrypted message data. You pass to it the created private key and the encryption algorithm (SecKeyAlgorithm) used before for encryption</li><li>You can transform the data back to a string and print it</li></ol><h3>Where to go?</h3><p>Check out the <strong>second and final part</strong> of this tutorial to learn about Digital signature and verification and how to achieve it through the ios devices’ secure enclave.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6571172d912" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Xcode and LLDB Advanced Debugging Tutorial: Part 3]]></title>
            <link>https://medium.com/@fadiderias/xcode-and-lldb-advanced-debugging-tutorial-part-3-8238aca63e7c?source=rss-da92204bda7b------2</link>
            <guid isPermaLink="false">https://medium.com/p/8238aca63e7c</guid>
            <category><![CDATA[debugging]]></category>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[wwdc]]></category>
            <category><![CDATA[xcode]]></category>
            <dc:creator><![CDATA[Fady Derias]]></dc:creator>
            <pubDate>Sun, 14 Oct 2018 04:42:46 GMT</pubDate>
            <atom:updated>2019-01-14T23:20:09.015Z</atom:updated>
            <content:encoded><![CDATA[<p>In the first and second parts of this three parts tutorial, we’ve covered how to utilize Xcode breakpoints to manipulate an existing property value and inject a new line of code via expression statements. We’ve also explored watchpoints that are a special type of breakpoints.</p><p>I developed a demo project with several intentional bugs to elaborate on how to use different types of breakpoints alongside the LLDB to fix bugs in your project/application.</p><p>If you didn’t go through <a href="https://medium.com/@fadiderias/xcode-and-lldb-advanced-debugging-tutorial-part-1-31919aa149e0"><strong>part 1</strong></a><strong> </strong>and<strong> </strong><a href="https://medium.com/@fadiderias/xcode-and-lldb-advanced-debugging-tutorial-part-2-8bfeae4cdfdb"><strong>part 2</strong></a><strong> </strong>of this tutorial, it’s crucial to check them before proceeding with this final part.</p><p>One last time, the golden rule of this tutorial:<br>You’re not to stop the compiler or re-run the application after running it for the very first time. You’re fixing the bugs at runtime.</p><h3>Symbolic Breakpoints 🔶</h3><p>How are we doing so far?</p><blockquote>4. The left navigation bar label that indicates how many times the user did load posts is not being updated.</blockquote><p>Here are the steps to reproduce the last bug you’re to deal with:</p><p>✦ Scroll to the top of the table view, and pull down to refresh.<br>✦ Scroll to the bottom of the table view to load new posts. [for 7 times 😉]<br>✦ The left label is not being updated for every time new posts are successfully retrieved.</p><p>It’s important to point out that the integer pageNumber property answers the question, how many times the user did load posts..? (i.e. the left label on the navigation bar should be updated by the value of the pageNumber property). We’re quite sure from the previous fixes that the pageNumber property is updated properly, hence the problem is with setting its value to the dedicated label on the navigation bar.</p><p>In such cases, symbolic breakpoints strike in. Think of symbolic breakpoints as if the debugger is playing treasure hunt and you’re providing it with clues to get to that treasure. In your case, that happens to be the piece of code that updates the left label on the navigation bar.</p><p>Let me show you how to do that.</p><p>Show the breakpoint navigator, and click on the + button on the bottom left corner. Select symbolic breakpoint.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/610/1*nI_n_rCvxBS5ZILJqDVzrA.png" /></figure><p>Add the following symbol</p><pre>[UILabel setText:]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bd0Xm4s2qxGAAlPafpuHgQ.png" /></figure><p><strong>Don’t</strong> check the “Automatically continue after evaluating actions” box.</p><p>What we’re simply doing here is informing the debugger that whenever the setText function of any UILabel is called, it should pause. Notice that after creating the symbolic breakpoint, a child has been added.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/616/1*pCPLepbfpWKJrNUfpprfow.png" /></figure><p>It’s a feedback from the debugger that it was able to resolve the created symbolic breakpoint to a specific location inside UIKitCore framework. In other cases, the debugger might resolve the symbolic breakpoint to multiple locations.</p><p>Now you’re all set, pull down to refresh the posts table view. As soon as you release, the debugger will pause, and you’ll be seeing something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qxcTdnmPUempljXsANz62Q.png" /></figure><p>At this point, you’re looking at some assembly code of the UIKitCore framework and on the left side is the stack trace that did cause the debugger to pause. The next thing we want to do is to inspect the arguments passed into the Objective-C message the debugger did pause at. In the lldb console, type the following:</p><pre>po $arg1</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*V33e1RQgoWtwNI8qy-AVJQ.png" /></figure><p>This does point out to the register that holds the first argument. We can clearly see that the receiver of that Objective-C message is a UILabel instance. The UILabel instance has a text value that refers to a post label. It’s not what we are interested in, but let’s proceed with the registers inspection.</p><p>In the lldb console, type the following:</p><pre>po $arg2</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/276/1*RF7qzO66OUAAZ61TwKg2GA.png" /></figure><p>The $arg2 does always refer to the selector of the Objective-C message. In some cases, the lldb doesn’t implicitly know the types of the arguments, and hence we need to do some typecasting.</p><p>In the lldb console, type the following:</p><pre>po (SEL)$arg2</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/312/1*f7lc9OC3NZGDTpOssJ3PBQ.png" /></figure><p>Now, we can clearly see the selector of the current Obj-c message.</p><p>In the lldb console, type the following:</p><pre>po $arg3</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/502/1*saKLYWOujvPhkmf3qcBD5g.png" /></figure><p>The $arg3 does always refer to the first parameter passed into the method. In our case, that is the string that is passed to the setText method.</p><p>Continue the execution of the program. The debugger will pause again. Repeat the above steps and eventually, you’ll figure out that the objective-c message belongs to another label of a post in the table view. It’s quite nonsense to keep doing this over and over again till we reach the UILabel instance that we are interested in. Things can definitely be better.</p><p>One thing you can do is to set a condition for the symbolic breakpoint to pause the debugger upon the success/fulfilment of that condition. This can be checking on a boolean value or waiting for a specific state to be reached .. etc.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bDOd5KQn_VzWy8mA6OEcVA.png" /></figure><p>However, we’re going for a different approach.</p><h4><strong>One Shot!</strong></h4><p>Disable the symbolic breakpoint you’ve created. <br>Logically speaking, the left navigation bar label that indicates how many times the user did load posts is updated after the posts are successfully retrieved via the HTTP GET request. Navigate to the section with the pragma mark Networking. Place a breakpoint inside the success completion handler of loadPosts. It should be <strong>below</strong>:</p><p><strong>Objective-C</strong></p><pre>[self.tableView reloadData];</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7MH01DMLDpUFGrBz0P4MkA.png" /></figure><p><strong>Swift</strong></p><pre>self.tableView.reloadData()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I69SoCZ3fAlaviM0WUWTXA.png" /></figure><p>This will assure that the symbolic breakpoint will get triggered only after the table view has been reloaded and all of its equivalent labels have been updated.</p><p><strong>Don’t</strong> check the “Automatically continue after evaluating actions” box. Add the following debugger command action:</p><pre>breakpoint set --one-shot true -name &#39;-[UILabel setText:]&#39;</pre><p>🤨🧐🤔</p><p>Let’s break that command:</p><ol><li>breakpoint set --one-shot true does create a “one-shot” breakpoint. A one-shot breakpoint is a type of breakpoint that only exists till it’s triggered then it gets automatically deleted.</li><li>-name ‘- [UILabel setText:]’ does set a symbolic name to the created one-shot breakpoint. It’s quite similar to the one you created in the last section.</li></ol><p>Let me recap this part. Here’s what you did:</p><ol><li>Adding a breakpoint (A) in the success completion handler of the function that executes the posts GET request.</li><li>Adding a debugger command action to <strong><em>create</em></strong> a symbolic breakpoint (B) similar to the one you created the last section. Its symbol is the UILabel setText function.</li><li>Setting the symbolic breakpoint (B) you created to be a one-shot breakpoint. It’s guaranteed that the symbolic breakpoint will pause the debugger only once since a one-shot breakpoint gets deleted automatically after it has been triggered.</li><li>Breakpoint (A) is located after reloading the table view so that the created symbolic breakpoint (B) doesn’t pause the debugger for any of the labels related to the table view.</li></ol><p>Now pull down the table view to refresh. Here’s what you’ll get:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JLBQAj7srx3twyCnScnVSg.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1022/1*2gcJPkL-VZ3HIebwOsqMZA.png" /><figcaption>Swift</figcaption></figure><p>The debugger did pause at the breakpoint (A) and hence setting the one-shot symbolic breakpoint.</p><p>Continue the program execution.</p><p>You’re back to the assembly code of the UIKitCore framework.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qxcTdnmPUempljXsANz62Q.png" /></figure><p>Let’s inspect the Objective-C message of the symbolic breakpoint arguments.</p><p>In the lldb console, type the following:</p><pre>po $arg1</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U7on9rNp2KTxH0vBu_5pwg.png" /></figure><p>WELL WELL WELL, looks like you finally found your treasure !! 🥇🏆🎉</p><p>Time to shift our sights to the stack trace. <strong>Step to point 1.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kx3XCFR0kcnpD5XC1tqtng.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*42LvhyQXygvMOF0dWphR2g.png" /><figcaption>Swift</figcaption></figure><p>It led you to the piece of code that is updating the pageNumberLabel text. It’s quite obvious that the text is always set to a string with a format of integer value 0 rather than the pageNumber property. Let’s test it before we make actual changes to our code.</p><p>You’re an expert now 🧢</p><p>Add a breakpoint in a separate line below the marked line of code. Add the following debugger command action:</p><p><strong>Objective-C</strong></p><pre>expression self.pageNumberLabel.text = [NSString stringWithFormat:@&quot;Page %tu&quot;, self.pageNumber]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VzRgynkwtDmcMFBveP1BrQ.png" /></figure><p><strong>Swift</strong></p><pre>expression pageNumberLabel.text = String(format: &quot;Page %tu&quot;, pageNumber)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IreVT3ZC9rTiC8B60WcxSw.png" /></figure><p>Remove/Disable breakpoint(A), accordingly, this will disable breakpoint(B)</p><p>Now pull to refresh and scroll to load more posts. The left navigation bar label is being updated. 🎉</p><p>Mission Accomplished !! 💪 💪</p><p>You can now stop the compiler and add the fixes we discussed in your code.</p><h4><strong>Summary</strong></h4><p>In this tutorial, you’ve learned</p><ol><li>How to use breakpoints alongside debugger action expression statements to manipulate existing values/properties.</li><li>How to use breakpoints alongside debugger action expression statements to inject lines of code.</li><li>How to set watchpoints to certain properties to monitor their values when being updated.</li><li>How to use symbolic breakpoints to pause the debugger based on defined symbols.</li><li>How to use one-shot breakpoints.</li><li>How to use one-shot breakpoints alongside symbolic breakpoint.</li></ol><p>Happy Debugging!! 😊</p><h4><strong>Third-party tools</strong></h4><p>I’ve used the following third-party tools for the convenience of this tutorial</p><ul><li><a href="https://github.com/typicode">typicode</a>/<a href="https://github.com/typicode/json-server">json-server</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8238aca63e7c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Xcode and LLDB Advanced Debugging Tutorial: Part 2]]></title>
            <link>https://medium.com/@fadiderias/xcode-and-lldb-advanced-debugging-tutorial-part-2-8bfeae4cdfdb?source=rss-da92204bda7b------2</link>
            <guid isPermaLink="false">https://medium.com/p/8bfeae4cdfdb</guid>
            <category><![CDATA[debugging]]></category>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[wwdc]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Fady Derias]]></dc:creator>
            <pubDate>Sun, 14 Oct 2018 04:41:37 GMT</pubDate>
            <atom:updated>2018-10-19T14:03:26.637Z</atom:updated>
            <content:encoded><![CDATA[<p>In the first part of this three parts tutorial, we’ve covered how to utilize Xcode breakpoints to manipulate an existing property value and inject a new line of code via expression statements.</p><p>I developed a demo project with several intentional bugs to elaborate on how to use different types of breakpoints alongside the LLDB to fix bugs in your project/application.</p><p>If you didn’t go through <a href="https://medium.com/@fadiderias/xcode-and-lldb-advanced-debugging-tutorial-part-1-31919aa149e0"><strong>part 1</strong></a> of this tutorial, it’s crucial to check it before proceeding with this part.</p><p>Let me remind you of the golden rule of this tutorial:<br>You’re not to stop the compiler or re-run the application after running it for the very first time. You’re fixing the bugs at runtime.</p><h3>Watchpoints 👀</h3><p>Let’s march to our next enemy.</p><blockquote>3. The user is allowed to load posts <strong>more </strong>than 7 times.</blockquote><p>Here are the steps to reproduce this one:</p><p>✦ Turn your iPhone’s/Simulator’s internet connection on.<br>✦ Scroll to the bottom of the table view to load more posts.<br>✦ Scrolling/loading more posts is valid for more than 7 times. (Bear in mind that for the current application, the user is only allowed to load posts for 7 times only)</p><p>One approach to consider this bug is to figure out how the pageNumber integer property is being updated since it’s passed to the networking manager to retrieve new posts objects for a specific page. In a code base that you’re still unaware of, it would take you some time and effort to figure out where exactly this is happening.</p><p>Worry not! Let’s do some magic 🎩</p><p>From part 1 of this tutorial, you learned that the GET HTTP request is executed in the section with the pragma mark Networking. It only includes one function which is loadPosts. Place a breakpoint on the first line of this function and pull down to refresh to reload new posts objects. This will trigger the breakpoint you’ve just added.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yCeuuv8HfObRgYewJLwhyA.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*czpn47AuKgaGvyIv5ImIIQ.png" /><figcaption>Swift</figcaption></figure><p>In the bottom debugger window, tap on the “Show variables view button”. This will slide a new view that includes all of the properties for <em>PostsTableViewController</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PbTSXBMHhfXOKxfe_Tec8Q.png" /></figure><p>Head to the pageNumber property, right-click, and select “Watch _pageNumber” / “Watch pageNumber”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rrJVnhAGpu-pxhNt7CFIBg.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bayE0ZKUW5wwccGdtc7gQQ.png" /><figcaption>Swift</figcaption></figure><p>That resulted in creating what is so-called a “Watchpoint” to the pageNumber property. A watchpoint is a type of breakpoint that pauses the debugger the next time the value of the property it’s set to get changed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*CSbAyFyweJdaU3lfnXebnw.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/542/1*qJXkvHWpGmHI7DquZW5zZA.png" /><figcaption>Swift</figcaption></figure><p>Continue the program execution. The debugger will pause and you’ll see something like this:</p><h4>Objective-C</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PEH5x-D85rp9qYo9MtwiJw.png" /></figure><ol><li>Logs of the old and new values of the pageNumber property.</li><li>The stack trace of the code that resulted in the change of the pageNumber property.</li><li>The current point that is causing the actual change of the pageNumber property. That is the setter method of the property.</li></ol><p>If you fall back to point 1 in the stack trace, it will lead you to the following piece of code:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/930/1*6rOdWkY4TxqbzLZfTCZJeg.png" /></figure><h4>Swift</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1AGmy4ThuDgFizPn_2mFSA.png" /></figure><ol><li>Debugger console informing you that the watchpoint you did set got hit.</li><li>The stack trace of the code that resulted in the change of the pageNumber property.</li><li>The current point that is causing the actual change of the pageNumber property. That is the updateForNetworkCallEnd function.</li></ol><p>It’s obvious to conclude that for every time the HTTP GET request succeeds, the pageNumber property will increment by 1 as long as the state enum property is active. The state enum property can be one of two values either “active” or “inactive”. An active state refers that the user is able to load more posts (i.e didn’t reach the load limit [7]). The inactive state is the mere opposite to that. In conclusion, we need to implement some logic inside the updateForNetworkCallEnd that checks on the pageNumber property and sets the state enum property accordingly.</p><p>As you’ve learned, it’s quite better to test the hypothesis first and then make actual changes to your code without stopping the compiler.</p><p>You’ve guessed it right 😉</p><p>It’s important to note that there’s an already implemented function under the section with the pragma mark Support that does set the state enum property to inactive. That is setToInactiveState.</p><p>Add a breakpoint one line above the if condition. Add a debugger command action. Add the following debugger command.</p><h4>Objective-C</h4><pre>expression if (self.pageNumber &gt;= 7) {[self setToInactiveState]}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2oH3kYHboDK5XUnX0vT3Qg.png" /></figure><h4>Swift</h4><pre>expression if (self.pageNumber &gt;= 7) {setToInactiveState()}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hcNVcXsvH-sGqP5-PdMjmg.png" /></figure><p>After doing that, you need to deactivate the very first breakpoint you did utilize to set the watchpoint. Disable the watchpoint as well.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u9im1mihdCdGDJSoAJfAzg.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/614/1*-fCWpD7jlLFw8LjxX92JXg.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5a1UhRJ5tXFZKJrdjOv2Ow.png" /><figcaption>Swift</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/544/1*S0ttr15900z7q-6znr19yA.png" /><figcaption>Swift</figcaption></figure><p>Now get back to the top of the table view, pull down to refresh, and then start scrolling down.</p><p><strong>Don’t party yet, we still have one more bug to kill</strong> 😄⚔️</p><h3>Where to go?</h3><p>Check out the <a href="https://medium.com/@fadiderias/xcode-and-lldb-advanced-debugging-tutorial-part-3-8238aca63e7c"><strong>third and final part</strong></a> of this tutorial to fix the last bug and learn about a new type of breakpoints that is symbolic breakpoints.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8bfeae4cdfdb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Xcode and LLDB Advanced Debugging Tutorial: Part 1]]></title>
            <link>https://medium.com/@fadiderias/xcode-and-lldb-advanced-debugging-tutorial-part-1-31919aa149e0?source=rss-da92204bda7b------2</link>
            <guid isPermaLink="false">https://medium.com/p/31919aa149e0</guid>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[wwdc]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[debugging]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Fady Derias]]></dc:creator>
            <pubDate>Sun, 14 Oct 2018 04:38:30 GMT</pubDate>
            <atom:updated>2018-10-14T04:46:16.307Z</atom:updated>
            <content:encoded><![CDATA[<p>One of the very intriguing sessions carried out by some of Apple’s finest debugging engineers during 2018’s WWDC was <a href="https://developer.apple.com/videos/play/wwdc2018/412/">Advanced Debugging with Xcode and LLDB</a>. They informed us about some impressive tips and tricks on how to utilize Xcode’s breakpoints and low-level debugger (LLDB) to optimize the debugging process whenever it happens that developers encounter bugs and all out to fix them.</p><p>In this 3 parts tutorial, I’ll walk you through most of what has been concluded in that WWDC session. I created a demo project specifically to elaborate on how to use different types of breakpoints alongside the LLDB to fix bugs in your project/application.</p><h4><strong>Demo Project</strong></h4><p>I developed a project of conventional tasks that most of the iOS developers out there have definitely dealt with at some point. It’s important to learn about its features/rules before proceeding with this article. Here’s what the demo project is all about:</p><ol><li>A table view controller that loads a list of posts when opened for the first time.</li><li>The table view controller supports loading more posts when reaching the bottom end of the table view.</li><li>The number of times the user is allowed to load posts is <strong>restricted to 7</strong>.</li><li>The user is able to reload new posts via a refresh controller (pull down to refresh).</li><li>There are two labels on the navigation bar that do indicate how many posts have been retrieved (right label) and how many times have the user loaded posts (left label).</li></ol><p>You can download it from <a href="https://github.com/FadyDerias/IBGPosts">here</a> if you’re an Objective-C player.<br>Swift player? Download it from <a href="https://github.com/FadyDerias/IBGPostsSwift">here</a>. <br>Xcode and run it! 😉</p><h3><strong>Bugs to Fix!</strong></h3><p>Now that you’re ready with your project, you might have noticed the following bugs:</p><ol><li>Pull down to refresh does not reload new posts.</li><li>The user is not receiving an alert (via an alert controller) whenever the HTTP request fails due to connection problems.</li><li>The user is allowed to load posts <strong>more </strong>than 7 times.</li><li>The left navigation bar label that indicates how many times the user did load posts is not being updated.</li></ol><p><em>Golden Rule:</em> For the rest of this article, you’re not to stop the compiler or re-run the application after running it for the very first time. You’re fixing the bugs at runtime.</p><h3><strong>The Power of Expression</strong></h3><p>Let’s tackle the first bug.</p><blockquote>1. Pull down to refresh does not reload new posts.</blockquote><p>Here are the steps to reproduce it:</p><p>✦ Run the application → the first 10 posts are loaded.<br>✦ Scroll down to load more posts.<br>✦ Scroll up to the top of the table view, and pull down to refresh.<br>✦ New posts are <strong>not </strong>reloaded and the old posts still exist &amp; the posts count is not reset.</p><p>A typical approach to fix this bug is to investigate what happens inside the selector method that is assigned to the dedicated UIRefreshControl of the table view controller. Head to <em>PostsTableViewController</em> and navigate to the section with the pragma mark Refresh control support. We can deduce from thesetupRefreshControl function that the selector dedicated for the refresh control is the reloadNewPosts function. Let’s add a breakpoint at the first line of this function and debug exactly what’s going on in there. Now scroll to the top of the table view and pull down to refresh it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/838/1*t3vOwPZMfYXA33XraHBReQ.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/826/1*5o64at1-25xhG8x7MOQCcQ.png" /><figcaption>Swift</figcaption></figure><p>The debugger has paused at the breakpoint you did set once you have released the refresh control. Now to further explore what happens next, tap on the debugger step over button.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/834/1*NnCfWSc4ALsmVW4MtVDmsQ.png" /><figcaption>Objective-C</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/854/1*O9EsnTPL8Bc7eRaDnggkNQ.png" /><figcaption>Swift</figcaption></figure><p>Now we have a clear idea what wrong is going on !!</p><p>The if statement condition is not satisfied (i.e theisPullDownToRefreshEnabled boolean property is set to NO) and hence the equivalent code for reloading the posts is not executed.</p><p>The typical approach to fix this is to stop the compiler, set the isPullDownToRefreshEnabled property to YES/true and that would do it. But it’s more convenient to test such a hypothesis before implementing some actual changes to the code and without the need to stop the compiler. Here come the breakpoint debugger command actions of expression statements really handy.</p><p>Double tap on the set breakpoint, or right click, edit breakpoint and tap on the “Add Action” button. Select “Debugger Command” action.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/978/1*5Q7AfSRWER__yCY-ygHrxA.png" /></figure><p>Now what we want to do is set the isPullDownToRefreshEnabled property to YES/true. Add the following debugger command.</p><p><strong>Objective-C</strong></p><pre>expression self.isPullDownToRefreshEnabled = YES</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1006/1*lAJyDbhVTYjwfBzKszTDig.png" /></figure><p><strong>Swift</strong></p><pre>expression self.isPullDownToRefreshEnabled = true</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xY2IFUHIJQkqBSddN5hmog.png" /></figure><p>The next thing you should do is checking the “Automatically continue after evaluating actions” box. This will cause the debugger <strong>not</strong> to pause at the breakpoint for each and every-time it gets triggered and automatically continue after evaluating the expression you just added.</p><p>Now scroll to the top of the table view and pull down to refresh.<br><strong>voilà </strong>new<strong> </strong>posts have been retrieved, replacing the old ones, and hence the posts count got updated.</p><p>As you’ve just resolved the first bug, pick up your anti-bugs weapons and proceed to the second one.</p><blockquote>2. The user is not receiving an alert (via an alert controller) whenever the HTTP request fails due to connection problems.</blockquote><p>Here are the steps to reproduce this one:</p><p>✦ Turn off your iPhone’s/Simulator’s internet connection.<br>✦ Scroll to the top of the table view, and pull down to refresh.<br>✦ No new posts are loaded due to network error.<br>✦ A network error alert controller is not presented to the user.</p><p>Head to <em>PostsTableViewController</em> and navigate to the section with the pragma mark Networking. It only includes one function which is loadPosts. It utilizes a shared instance of a networking manager to execute a GET HTTP request that returns an array of posts object via a “success” completion handler or an instance of NSError via a “failure” completion handler.</p><p>What we want to do is to add some code inside the failure completion handler to present a networking error alert controller. If you navigated to the section with the pragma mark Support, you’ll find that there’s an already implemented function presentNetworkFailureAlertController that does handle the presentation of the required alert controller. All that we need to do is to call that function inside the loadPosts failure completion handler.</p><p>The conventional way is to stop the compiler, add the required line of code and you’re done. Let’s go for the unconventional!</p><p>Add a breakpoint inside the failure completion handler <strong>below</strong> the line</p><p><strong>Objective-C</strong></p><pre>[self updateUIForNetworkCallEnd];</pre><p><strong>Swift</strong></p><pre>self.updateUIForNetworkCallEnd()</pre><p>Double tap on the set breakpoint, tap on the “Add Action” button. Select debugger command action. Add the following debugger command</p><p><strong>Objective-C</strong></p><pre>expression [self presentNetworkFailureAlertController]</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q1RqsI7GGn5Nx7MI9oaOFA.png" /></figure><p><strong>Swift</strong></p><pre>expression self.presentNetworkFailureAlertController()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*o1j-d1NS0j0DOBJlySEM6A.png" /></figure><p>Check the “Automatically continue after evaluating actions” box.</p><p>With your internet connection disabled, scroll to the top of the table view and pull down to refresh or you can scroll down to the bottom of the table view in an attempt to load more posts. Here’s what you get 🎉🎉</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/994/1*Ohh02CA-HA3rqtgmx7atPQ.png" /></figure><p>What you just did was <strong>“injecting”</strong> a line of code with an expression statement implemented as a debugger command action inside a dedicated breakpoint.</p><h3>Recap</h3><p>Let me just recap what we did with breakpoints debugger command action expression statements:</p><ol><li>Manipulate an existing property value.</li><li>Injecting a new line of code.</li></ol><p>Both tasks were achieved at runtime. We didn’t really need to stop the compiler, modify things and then re-run the application.</p><h3>Where to go?</h3><p>Check out the <a href="https://medium.com/@fadiderias/xcode-and-lldb-advanced-debugging-tutorial-part-2-8bfeae4cdfdb"><strong>second part</strong></a> of this tutorial to fix extra bugs and learn about a special type of breakpoints, that is watchpoints.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=31919aa149e0" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>