{"componentChunkName":"component---src-templates-tag-js","path":"/tags/troubleshoot/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"fields":{"slug":"/engineering/how-to-obtain-ios-application-logs-without-mac/"},"html":"<p>Logs are very helpful in finding the root cause of the issues you may be experiencing in an app. It is an efficient way to resolve issues by knowing the exact reason after checking Logs.</p>\n<p>Let's say we have developed an iOS app. As in many situations, we want to test our app on another's phone for many reasons. And probably that phone cannot be connected to the Mac. So, the console logs of the app can be sent directly from the app to the developer(us).</p>\n<p>This blog will provide step-by-step instructions for mailing iOS app logs directly from the app. </p>\n<h3 id=\"getting-started\" style=\"position:relative;\"><a href=\"#getting-started\" aria-label=\"getting started permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Getting started</h3>\n<p>Here we are having a <a href=\"https://github.com/tanvijn/TestLogs/tree/master\">project</a> with a single ViewController. We may ask our users to install the app on their device, use it and at the end click on “Press for Logs” Button. By clicking IBAction pressForLogs function will get called which will open MailComposer and then the user can mail the Log file to us.</p>\n<h3 id=\"steps-to-do-in-your-own-project\" style=\"position:relative;\"><a href=\"#steps-to-do-in-your-own-project\" aria-label=\"steps to do in your own project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Steps to do in your own project</h3>\n<ul>\n<li>Find AppDelegate.swift in your project. Define following var and function as global before any import statement.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">logFilePath</span><span class=\"mtk15\">:</span><span class=\"mtk1\">String!</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//======================//</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">func </span><span class=\"mtk11\">print</span><span class=\"mtk1\">(</span><span class=\"mtk10\">_</span><span class=\"mtk1\"> </span><span class=\"mtk12\">items</span><span class=\"mtk15\">:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Any</span><span class=\"mtk1\">..., separator</span><span class=\"mtk15\">:</span><span class=\"mtk1\"> String = </span><span class=\"mtk8\">&quot; &quot;</span><span class=\"mtk1\">, terminator</span><span class=\"mtk15\">:</span><span class=\"mtk1\"> String = </span><span class=\"mtk8\">&quot;</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let output = </span><span class=\"mtk12\">items</span><span class=\"mtk1\">.</span><span class=\"mtk12\">map</span><span class=\"mtk1\"> { </span><span class=\"mtk8\">&quot;*</span><span class=\"mtk6\">\\(</span><span class=\"mtk8\">$0)&quot;</span><span class=\"mtk1\">}.</span><span class=\"mtk11\">joined</span><span class=\"mtk1\">(separator</span><span class=\"mtk15\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot; &quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//Swift.print(output, terminator: terminator)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">NSLog</span><span class=\"mtk1\">(output)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p> Above function override any log calls in the app.</p>\n<ul>\n<li>Then define the following method in AppDelegate.Swift file. And call from <code>func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool function.</code></li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"swift\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">printTheDataAtLogFile</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    logFilePath = </span><span class=\"mtk11\">NSTemporaryDirectory</span><span class=\"mtk1\">().</span><span class=\"mtk11\">appending</span><span class=\"mtk1\">(</span><span class=\"mtk10\">String</span><span class=\"mtk1\">.</span><span class=\"mtk4\">init</span><span class=\"mtk1\">(</span><span class=\"mtk11\">format</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;%@.log&quot;</span><span class=\"mtk1\">,Bundle.</span><span class=\"mtk12\">main</span><span class=\"mtk1\">.</span><span class=\"mtk11\">object</span><span class=\"mtk1\">(</span><span class=\"mtk11\">forInfoDictionaryKey</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;CFBundleName&quot;</span><span class=\"mtk1\">) as! </span><span class=\"mtk10\">String</span><span class=\"mtk1\">)) as </span><span class=\"mtk10\">String</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk11\">freopen</span><span class=\"mtk1\">((logFilePath as NSString).</span><span class=\"mtk11\">cString</span><span class=\"mtk1\">(</span><span class=\"mtk11\">using</span><span class=\"mtk1\">: </span><span class=\"mtk10\">String</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Encoding</span><span class=\"mtk1\">(</span><span class=\"mtk11\">rawValue</span><span class=\"mtk1\">: </span><span class=\"mtk10\">String</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Encoding</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ascii</span><span class=\"mtk1\">.</span><span class=\"mtk12\">rawValue</span><span class=\"mtk1\">).</span><span class=\"mtk12\">rawValue</span><span class=\"mtk1\">)!, </span><span class=\"mtk8\">&quot;a+&quot;</span><span class=\"mtk1\">, stderr)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   }</span></span></code></pre>\n<p>Above function will write all logs into a file instead of console.</p>\n<ul>\n<li>\n<p>Open Viewcontroller.swift. Define below 2 functions in it. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"swift\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">allOptions</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">let</span><span class=\"mtk1\"> alert = </span><span class=\"mtk11\">UIAlertController</span><span class=\"mtk1\">(</span><span class=\"mtk11\">title</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Please Select an Option&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">message</span><span class=\"mtk1\">: </span><span class=\"mtk4\">nil</span><span class=\"mtk1\">, </span><span class=\"mtk11\">preferredStyle</span><span class=\"mtk1\">: .</span><span class=\"mtk12\">actionSheet</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">alert.</span><span class=\"mtk11\">addAction</span><span class=\"mtk1\">(</span><span class=\"mtk11\">UIAlertAction</span><span class=\"mtk1\">(</span><span class=\"mtk11\">title</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Log Mail&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">style</span><span class=\"mtk1\">: .</span><span class=\"mtk12\">default</span><span class=\"mtk1\"> , </span><span class=\"mtk11\">handler</span><span class=\"mtk1\">:{ (UIAlertAction)</span><span class=\"mtk15\">in</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.</span><span class=\"mtk11\">shareDocument</span><span class=\"mtk1\">(</span><span class=\"mtk11\">documentPath</span><span class=\"mtk1\">: logFilePath)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">alert.</span><span class=\"mtk11\">addAction</span><span class=\"mtk1\">(</span><span class=\"mtk11\">UIAlertAction</span><span class=\"mtk1\">(</span><span class=\"mtk11\">title</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;dismis&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">style</span><span class=\"mtk1\">: .</span><span class=\"mtk12\">cancel</span><span class=\"mtk1\">, </span><span class=\"mtk11\">handler</span><span class=\"mtk1\">:{ (UIAlertAction)</span><span class=\"mtk15\">in</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">print</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;User click Dismiss button&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">self</span><span class=\"mtk1\">.</span><span class=\"mtk11\">present</span><span class=\"mtk1\">(alert, </span><span class=\"mtk11\">animated</span><span class=\"mtk1\">: </span><span class=\"mtk4\">true</span><span class=\"mtk1\">, </span><span class=\"mtk11\">completion</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">print</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;completion block&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//  ============================= //</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">// this is to share file //</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">shareDocument</span><span class=\"mtk1\">(</span><span class=\"mtk11\">documentPath</span><span class=\"mtk1\">: </span><span class=\"mtk10\">String</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> FileManager.</span><span class=\"mtk12\">default</span><span class=\"mtk1\">.</span><span class=\"mtk11\">fileExists</span><span class=\"mtk1\">(</span><span class=\"mtk11\">atPath</span><span class=\"mtk1\">: documentPath){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> fileURL = </span><span class=\"mtk11\">URL</span><span class=\"mtk1\">(</span><span class=\"mtk11\">fileURLWithPath</span><span class=\"mtk1\">: documentPath)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> activityViewController: UIActivityViewController = </span><span class=\"mtk11\">UIActivityViewController</span><span class=\"mtk1\">(</span><span class=\"mtk11\">activityItems</span><span class=\"mtk1\">: [fileURL], </span><span class=\"mtk11\">applicationActivities</span><span class=\"mtk1\">: </span><span class=\"mtk4\">nil</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  activityViewController.</span><span class=\"mtk12\">popoverPresentationController</span><span class=\"mtk1\">?.</span><span class=\"mtk12\">sourceView</span><span class=\"mtk1\">=</span><span class=\"mtk4\">self</span><span class=\"mtk1\">.</span><span class=\"mtk12\">view</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">present</span><span class=\"mtk1\">(activityViewController, </span><span class=\"mtk11\">animated</span><span class=\"mtk1\">: </span><span class=\"mtk4\">true</span><span class=\"mtk1\">, </span><span class=\"mtk11\">completion</span><span class=\"mtk1\">: </span><span class=\"mtk4\">nil</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">print</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Document was not found&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Call <code>allOptions()</code> from IBAction pressForLogs. Above functions will open ActivityViewContrrolle to let the user mail log file to you.</p>\n</li>\n</ul>\n<h4 id=\"voila-\" style=\"position:relative;\"><a href=\"#voila-\" aria-label=\"voila  permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Voila!! :)</h4>\n<p>Thanks for visiting us! We hope you find this knowledge base useful! Our mission is to make mobile app development happy. We hope we’re living up to the mission with your project.</p>\n<p>Please write to us for suggestions and for the contents we should come up with!</p>\n<p>Thanks for reading the blog. For detailed information and execution example of this blog, please refer to the video below:</p>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/KTnFtIvoDiI\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"date":"July 22, 2020","updated_date":null,"title":"How to obtain iOS application logs without Mac","tags":["Logs","ios","xcode","iPhone","troubleshoot","Mac"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/d20c2fa69dbca2ed569074ba6253a8e3/ee604/Log.png","srcSet":"/static/d20c2fa69dbca2ed569074ba6253a8e3/69585/Log.png 200w,\n/static/d20c2fa69dbca2ed569074ba6253a8e3/497c6/Log.png 400w,\n/static/d20c2fa69dbca2ed569074ba6253a8e3/ee604/Log.png 800w,\n/static/d20c2fa69dbca2ed569074ba6253a8e3/f3583/Log.png 1200w,\n/static/d20c2fa69dbca2ed569074ba6253a8e3/0dadc/Log.png 1500w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Tanvi Jain","github":"tanvijn","avatar":null}}}}]}},"pageContext":{"tag":"troubleshoot"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}