{"id":350,"date":"2016-07-08T11:27:52","date_gmt":"2016-07-08T09:27:52","guid":{"rendered":"https:\/\/zaven.co\/blog\/?p=350"},"modified":"2025-04-08T19:55:20","modified_gmt":"2025-04-08T17:55:20","slug":"add-extensions-ios-apps","status":"publish","type":"post","link":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/","title":{"rendered":"How to add extensions to iOS apps (part 4)"},"content":{"rendered":"<p>Welcome to the last part of our tutorial: <a href=\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps-2\/\">how to add extensions to iOS apps<\/a>. In this part, <strong>we will learn how to add data using a service from our extension<\/strong>.<!--more--><\/p>\n<p>In part three of \u201cHow to add extensions to iOS apps\u201d we finished <a href=\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps-part3\/\">table implementation in the main app<\/a>.<\/p>\n<h2>Adding files<\/h2>\n<p>Start by opening the <code>ActionViewController<\/code> of our extension. We can see quite a lot of code here.<\/p>\n<p>By default, <strong>it is used for handling photos which are opened through the extension<\/strong>. We\u2019re going to modify this template (or rather \u201crewrite it\u201d). The first step is to delete the function logic in <code>viewDidLoad()<\/code>.<\/p>\n<pre><code class=\"language-swift\">\nimport UIKit\nimport MobileCoreServices\n\nclass ActionViewController: UIViewController {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n    }\n    \n    override func didReceiveMemoryWarning() {\n        super.didReceiveMemoryWarning()\n    }\n\t\n\t@IBAction func done() {\n\t\tself.extensionContext!.completeRequestReturningItems(self.extensionContext!.inputItems, completionHandler: nil)\n\t}\n\n}\n<\/code><\/pre>\n<p>We\u2019ll get back to it in a minute, but let\u2019s have a look at the <code>Info.plist<\/code> file in our extension. We must define what kind of files will it accept. Look for a setting called <code>NSExtension<\/code>: there you can find a dictionary called <code>NSExtensionAttributes<\/code> with the <code>NSExtensionActivationRule<\/code> key. Determine the file types there.<\/p>\n<div id=\"attachment_405\" style=\"width: 733px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/17-1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-405\" class=\"wp-image-405 size-full\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/17-1.png\" alt=\"how to add data using a service from extension\"  ><\/a><p id=\"caption-attachment-405\" class=\"wp-caption-text\">Defining file types<\/p><\/div>\n<p>If you\u2019d like to find out more, you can find the <a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/General\/Reference\/InfoPlistKeyReference\/Articles\/SystemExtensionKeys.html#\/\/apple_ref\/doc\/uid\/TP40014212-SW10\" rel=\"nofollow\">docs for this topic<\/a> here. Apple provides a few elementary file types which we can use. Unfortunately, there are only a couple of them. And sometimes it turns out that they are too common for an app\u2019s specific requirements. In that case, it is useful to find out what the <a href=\"https:\/\/developer.apple.com\/library\/ios\/documentation\/FileManagement\/Conceptual\/understanding_utis\/understand_utis_conc\/understand_utis_conc.html#\/\/apple_ref\/doc\/uid\/TP40001319-CH202-CHDHIJDE\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">UTI<\/a> is. We will use a <a href=\"https:\/\/developer.apple.com\/library\/ios\/documentation\/Miscellaneous\/Reference\/UTIRef\/Articles\/System-DeclaredUniformTypeIdentifiers.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">table<\/a> in which all required file types stored.<\/p>\n<p>Assume that I want the extension to accept only<em>.pdf<\/em>, <em>.txt <\/em>and .<em>doc<\/em> extensions. <em>We need more than basic settings to determine these types of files<\/em>. To make it easier, we can use <code>Predicate Format String<\/code>. Right-click the file<code>Info.plist <\/code>and select <code>Open As\/Source Code<\/code>.<\/p>\n<p>Now we can see <strong>the content of an XML format file<\/strong>. Look for a key called <code>NSExtensionActivationRule<\/code> and delete the string <code>TRUEPREDICATE<\/code>. By default, this string enables all file types (but this also guarantees our app to be rejected from the App Store).<\/p>\n<p>Instead of this string, paste following one:<\/p>\n<pre><code class=\"language-xml\">\n&lt;key&gt;NSExtensionActivationRule&lt;\/key&gt;\n&lt;string&gt;SUBQUERY (\n  extensionItems,\n  $extensionItem,\n  SUBQUERY (\n    $extensionItem.attachments,\n    $attachment,\n    ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO \"com.adobe.pdf\" ||\n    ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO \"public.plain-text\" ||\n    ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO \"com.microsoft.word.doc\"\n  ).@count == $extensionItem.attachments.@count\n).@count == 1&lt;\/string&gt;\n<\/code><\/pre>\n<p>It allows us to use the following types of files:<\/p>\n<ul>\n<li>com.adobe.pdf (PDF)<\/li>\n<li>public.plain-text (TXT)<\/li>\n<li>com.microsoft.word.doc (DOC)<\/li>\n<\/ul>\n<p>The file content should look like this:<\/p>\n<pre><code class=\"language-xml\">\n&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n&lt;!DOCTYPE plist PUBLIC \"-\/\/Apple\/\/DTD PLIST 1.0\/\/EN\" \"http:\/\/www.apple.com\/DTDs\/PropertyList-1.0.dtd\"&gt;\n&lt;plist version=\"1.0\"&gt;\n&lt;dict&gt;\n   &lt;key&gt;CFBundleDevelopmentRegion&lt;\/key&gt;\n   &lt;string&gt;en&lt;\/string&gt;\n   &lt;key&gt;CFBundleDisplayName&lt;\/key&gt;\n   &lt;string&gt;AppExtenstionSampleAction&lt;\/string&gt;\n   &lt;key&gt;CFBundleExecutable&lt;\/key&gt;\n   &lt;string&gt;$(EXECUTABLE_NAME)&lt;\/string&gt;\n   &lt;key&gt;CFBundleIdentifier&lt;\/key&gt;\n   &lt;string&gt;$(PRODUCT_BUNDLE_IDENTIFIER)&lt;\/string&gt;\n   &lt;key&gt;CFBundleInfoDictionaryVersion&lt;\/key&gt;\n   &lt;string&gt;6.0&lt;\/string&gt;\n   &lt;key&gt;CFBundleName&lt;\/key&gt;\n   &lt;string&gt;$(PRODUCT_NAME)&lt;\/string&gt;\n   &lt;key&gt;CFBundlePackageType&lt;\/key&gt;\n   &lt;string&gt;XPC!&lt;\/string&gt;\n   &lt;key&gt;CFBundleShortVersionString&lt;\/key&gt;\n   &lt;string&gt;1.0&lt;\/string&gt;\n   &lt;key&gt;CFBundleSignature&lt;\/key&gt;\n   &lt;string&gt;????&lt;\/string&gt;\n   &lt;key&gt;CFBundleVersion&lt;\/key&gt;\n   &lt;string&gt;1&lt;\/string&gt;\n   &lt;key&gt;NSExtension&lt;\/key&gt;\n   &lt;dict&gt;\n       &lt;key&gt;NSExtensionAttributes&lt;\/key&gt;\n       &lt;dict&gt;\n           &lt;key&gt;NSExtensionActivationRule&lt;\/key&gt;\n          &lt;string&gt;SUBQUERY (\n              extensionItems,\n              $extensionItem,\n              SUBQUERY (\n              $extensionItem.attachments,\n              $attachment,\n              ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO \"com.adobe.pdf\" ||\n              ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO \"public.plain-text\" ||\n              ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO \"com.microsoft.word.doc\"\n              ).@count == $extensionItem.attachments.@count\n              ).@count == 1&lt;\/string&gt;\n       &lt;\/dict&gt;\n       &lt;key&gt;NSExtensionMainStoryboard&lt;\/key&gt;\n       &lt;string&gt;MainInterface&lt;\/string&gt;\n       &lt;key&gt;NSExtensionPointIdentifier&lt;\/key&gt;\n       &lt;string&gt;com.apple.ui-services&lt;\/string&gt;\n   &lt;\/dict&gt;\n&lt;\/dict&gt;\n&lt;\/plist&gt;\n<\/code><\/pre>\n<p>Run the app and open a PDF file, then click the action button. <strong>The <code>Action Menu<\/code> that should appear will display a list of all the applications<\/strong> that can be used to open it.<\/p>\n<div id=\"attachment_410\" style=\"width: 210px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-410\" class=\"wp-image-410\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/19.png\" alt=\"iPhone app development\"  ><p id=\"caption-attachment-410\" class=\"wp-caption-text\">Action Menu<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>Our app won\u2019t be visible because we must manually activate it first (that\u2019s a standard behaviour for newly installed apps). Just tap \u201cMore\u201d and mark your app as activated. Then, approve it.<\/p>\n<div id=\"attachment_411\" style=\"width: 210px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/20.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-411\" class=\"wp-image-411\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/20.png\" alt=\"adding data from extension to iOS apps\"  ><\/a><p id=\"caption-attachment-411\" class=\"wp-caption-text\">Action Menu with our app<\/p><\/div>\n<p>Now the app is on our menu but nothing will happen if you choose it. That\u2019s because we have deleted from it all the logic that is responsible for handling the opened files.<\/p>\n<h2>Adding file view<\/h2>\n<p>Open our extension\u2019s storyboard titled <code>MainInterface<\/code> and delete <code>Image View<\/code> (it won\u2019t be needed). On top of the view, add a label to display the file name to be saved and and constraints below the \u201cSave\u201d button.<\/p>\n<div id=\"attachment_414\" style=\"width: 740px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/21.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-414\" class=\"wp-image-414 size-medium\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/21-730x620.png\" alt=\"Mobile enterprise solution\"   srcset=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/21-730x620.png 730w, https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/21.png 960w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/a><p id=\"caption-attachment-414\" class=\"wp-caption-text\">The extension&#8217;s storyboard<\/p><\/div>\n<p>Set an outlet for the label and an action for the button. Leave the \u201cDone\u201d button just like it is (it closes the view without changing the file).<\/p>\n<div id=\"attachment_415\" style=\"width: 740px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/22.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-415\" class=\"wp-image-415 size-medium\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/22-730x503.png\" alt=\"extension to iOS apps how to add data\"   srcset=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/22-730x503.png 730w, https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/22.png 1469w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/a><p id=\"caption-attachment-415\" class=\"wp-caption-text\">Setting an outlet for the label and an action for the button<\/p><\/div>\n<h2>Saving the file<\/h2>\n<p>Now we will save our file. But first, <strong>enable the extension to use main target classes<\/strong>. Open the project settings, choose our target on the left side and click the <code>Build Phases<\/code> bookmark. In <code>Compile Sources<\/code> area click the \u201d+\u201d button and choose the <code>LocalStorageManager class.<\/code><\/p>\n<div id=\"attachment_416\" style=\"width: 412px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/23.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-416\" class=\"wp-image-416 size-full\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/23.png\" alt=\"iOS app development how to add data\"  ><\/a><p id=\"caption-attachment-416\" class=\"wp-caption-text\">Adding LocalStorageManager<\/p><\/div>\n<p>This way we can <em>choose the sources to be compiled while building our target<\/em>. With that we don\u2019t need to recreate a class to handle our data container and so we can use the already created one.<\/p>\n<div id=\"attachment_417\" style=\"width: 740px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/24.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-417\" class=\"wp-image-417 size-medium\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/24-730x199.png\" alt=\"iOS app developer how to add data using a service\"   srcset=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/24-730x199.png 730w, https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/24.png 1468w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/a><p id=\"caption-attachment-417\" class=\"wp-caption-text\">Adding Compile Sources<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>Open <code>ActionViewController<\/code> and add the code needed for handling the opened file. Then add the two following methods:<\/p>\n<ul>\n<li>In the <code>processPickedFile()<\/code> method search for the file which we opened and then check if it belongs to one of the three extensions we whitelisted in the <code>plist<\/code> of our extension.<\/li>\n<li>If everything goes as planned, we can send the opened file to <code>setPickedFile()<\/code>. To set the file name as the label, we need the <code>lastPathComponent<\/code> from the file\u2019s <code>NSURL<\/code><\/li>\n<\/ul>\n<pre><code class=\"language-swift\">\n    func processPickedFile(){\n        if(self.extensionContext!.inputItems.count &gt; 0){\n            let inputItem = self.extensionContext?.inputItems.first as! NSExtensionItem\n            for provider: AnyObject in inputItem.attachments!{\n                let itemProvider = provider as! NSItemProvider\n                if(itemProvider.hasItemConformingToTypeIdentifier(kUTTypePDF as String) || itemProvider.hasItemConformingToTypeIdentifier(kUTTypePlainText as String) || itemProvider.hasItemConformingToTypeIdentifier(\"com.microsoft.word.doc\")){\n                    itemProvider.loadItemForTypeIdentifier(kUTTypePDF as String, options: nil, completionHandler: { (file, error) in\n                        if(error == nil){\n                            self.setPickedFile(file!)\n                        }\n                    })\n                    break\n                }\n            }\n        }\n    }\n    \n    func setPickedFile(file: NSSecureCoding){\n        if let fileURL = file as? NSURL{\n            let fileName = fileURL.lastPathComponent\n            self.fileNameLabel.text = fileName\n        }\n    }\n<\/code><\/pre>\n<p>Next, to the <code>saveButtonTouchUpInside()<\/code> method, which is connected with our \u201cSave\u201d button, add two lines:<\/p>\n<pre><code class=\"language-swift\">\nLocalStorageManager.sharedInstance.insertData(self.fileNameLabel.text!)\nself.extensionContext!.completeRequestReturningItems(self.extensionContext!.inputItems, completionHandler: nil)\n<\/code><\/pre>\n<p>Here we use the method created in our class to handle the container added as a binary to our extension. After adding the file, call the extension <code>close()<\/code> method.<\/p>\n<p>At the end add the <code>processPickedFile()<\/code> method to the <code>viewDidLoad(<\/code>) method. The code should look like this now:<\/p>\n<pre><code class=\"language-swift\">\nimport UIKit\nimport MobileCoreServices\n\nclass ActionViewController: UIViewController {\n    \n    @IBOutlet weak var fileNameLabel: UILabel!\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        self.processPickedFile()\n    }\n    \n    override func didReceiveMemoryWarning() {\n        super.didReceiveMemoryWarning()\n    }\n\n    func processPickedFile(){\n        if(self.extensionContext!.inputItems.count &gt; 0){\n            let inputItem = self.extensionContext?.inputItems.first as! NSExtensionItem\n            for provider: AnyObject in inputItem.attachments!{\n                let itemProvider = provider as! NSItemProvider\n                if(itemProvider.hasItemConformingToTypeIdentifier(kUTTypePDF as String) || itemProvider.hasItemConformingToTypeIdentifier(kUTTypePlainText as String) || itemProvider.hasItemConformingToTypeIdentifier(\"com.microsoft.word.doc\")){\n                    itemProvider.loadItemForTypeIdentifier(kUTTypePDF as String, options: nil, completionHandler: { (file, error) in\n                        if(error == nil){\n                            self.setPickedFile(file!)\n                        }\n                    })\n                    break\n                }\n            }\n        }\n    }\n    \n    func setPickedFile(file: NSSecureCoding){\n        if let fileURL = file as? NSURL{\n            let fileName = fileURL.lastPathComponent\n            self.fileNameLabel.text = fileName\n        }\n    }\n    \n    @IBAction func saveButtonTouchUpInside(sender: AnyObject) {\n        LocalStorageManager.sharedInstance.insertData(self.fileNameLabel.text!)\n        self.extensionContext!.completeRequestReturningItems(self.extensionContext!.inputItems, completionHandler: nil)\n    }\n    \n    @IBAction func done() {\n        self.extensionContext!.completeRequestReturningItems(self.extensionContext!.inputItems, completionHandler: nil)\n    }\n\n}\n<\/code><\/pre>\n<p>If you run the app and choose a file (of course, it can be only one of the file types we decided to support), a view with the file name should appear. You should be able to save the file.<\/p>\n<div id=\"attachment_418\" style=\"width: 210px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/26.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-418\" class=\"wp-image-418\" src=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/26.png\" alt=\"iOS apps\"  ><\/a><p id=\"caption-attachment-418\" class=\"wp-caption-text\">Running the app<\/p><\/div>\n<p>Saving the file should close the view. If we open the app now, we will see the app\u2019s name on the list.<\/p>\n<p>Let\u2019s make just one more change in our main target <code>ViewController<\/code>. At the end of the <code>viewDidLoad()<\/code> method, add the following line:<\/p>\n<pre><code class=\"language-swift\">\nNSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.viewWillEnterForeground(_:)), name:UIApplicationWillEnterForegroundNotification, object: nil)\n<\/code><\/pre>\n<p>Afterwards, add the method below that is suggested by the selector:<\/p>\n<pre><code class=\"language-swift\">\nfunc viewWillEnterForeground(notification: NSNotification){\n    self.tableView.reloadData()\n}\n<\/code><\/pre>\n<p>Thanks to that, if we switch to sleep mode and then run the app again, we can be sure that the table will refresh every time.<\/p>\n<hr>\n<h3>Conclusion<\/h3>\n<p>As you can see, creating your own app extension isn\u2019t that hard. But before doing that, your project must be properly prepared. <strong>Create a common container for the app, add classes as binaries to the extension, determine supported files types.<\/strong> And, of course, create the logic responsible for the file service itself.<\/p>\n<hr>\n<h3>You can have a look at the finished app in our <a href=\"https:\/\/github.com\/zavenco\/AppExtensionSample\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub repo<\/a>.<\/h3>\n<hr>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Welcome to the last part of our tutorial: how to add extensions to iOS apps. In this part, we will learn how to add data using a service from our extension.<\/p>\n","protected":false},"author":4,"featured_media":461,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57,5],"tags":[37,38,34,36,35],"class_list":["post-350","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ios-development","category-tutorials","tag-app-extension","tag-app-ios-developer","tag-ios-app-building","tag-ios-app-development","tag-iphone-app-development"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.8.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Adding data from extension to iOS apps. How to do it? | Zaven Blog<\/title>\n<meta name=\"description\" content=\"Welcome to the last part of our tutorial: how to add extensions to iOS apps. We will learn how to add data using a service from extension to iOS apps.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Adding data from extension to iOS apps. How to do it? | Zaven Blog\" \/>\n<meta property=\"og:description\" content=\"Welcome to the last part of our tutorial: how to add extensions to iOS apps. We will learn how to add data using a service from extension to iOS apps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/\" \/>\n<meta property=\"og:site_name\" content=\"Zaven Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-07-08T09:27:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-08T17:55:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/ostatnia-ostatnia.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2131\" \/>\n\t<meta property=\"og:image:height\" content=\"1223\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Pawe\u0142 Ku\u017aniak\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Pawe\u0142 Ku\u017aniak\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/\",\"url\":\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/\",\"name\":\"Adding data from extension to iOS apps. How to do it? | Zaven Blog\",\"isPartOf\":{\"@id\":\"https:\/\/zaven.co\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/ostatnia-ostatnia.jpg\",\"datePublished\":\"2016-07-08T09:27:52+00:00\",\"dateModified\":\"2025-04-08T17:55:20+00:00\",\"author\":{\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/c29fc600e8bb0269e5390d84f114ac54\"},\"description\":\"Welcome to the last part of our tutorial: how to add extensions to iOS apps. We will learn how to add data using a service from extension to iOS apps.\",\"breadcrumb\":{\"@id\":\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#primaryimage\",\"url\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/ostatnia-ostatnia.jpg\",\"contentUrl\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/ostatnia-ostatnia.jpg\",\"width\":2131,\"height\":1223,\"caption\":\"How to add extensions to iOS apps\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/zaven.co\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to add extensions to iOS apps (part 4)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/zaven.co\/blog\/#website\",\"url\":\"https:\/\/zaven.co\/blog\/\",\"name\":\"Zaven Blog\",\"description\":\"Software development blog. Generative AI, web &amp; mobile applications.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/zaven.co\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/c29fc600e8bb0269e5390d84f114ac54\",\"name\":\"Pawe\u0142 Ku\u017aniak\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/18ab5ae9a3e0bf0aaec573b90bbf3ea8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/18ab5ae9a3e0bf0aaec573b90bbf3ea8?s=96&d=mm&r=g\",\"caption\":\"Pawe\u0142 Ku\u017aniak\"},\"description\":\"Pawe\u0142 is technical analyst, developer and IT operations specialist at Zaven. He can solve a 3x3x3 Rubik's cube in a matter of seconds and you can find more complicated ones lying around on his desk (solved, obviously). His problem-solving attitude is reflected in his work, as he likes to keep himself busy with non-trivial puzzles.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/pawe-kuniak-a33735104\"],\"url\":\"https:\/\/zaven.co\/blog\/author\/pkuzniakzaven-pl\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Adding data from extension to iOS apps. How to do it? | Zaven Blog","description":"Welcome to the last part of our tutorial: how to add extensions to iOS apps. We will learn how to add data using a service from extension to iOS apps.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/","og_locale":"en_US","og_type":"article","og_title":"Adding data from extension to iOS apps. How to do it? | Zaven Blog","og_description":"Welcome to the last part of our tutorial: how to add extensions to iOS apps. We will learn how to add data using a service from extension to iOS apps.","og_url":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/","og_site_name":"Zaven Blog","article_published_time":"2016-07-08T09:27:52+00:00","article_modified_time":"2025-04-08T17:55:20+00:00","og_image":[{"width":2131,"height":1223,"url":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/ostatnia-ostatnia.jpg","type":"image\/jpeg"}],"author":"Pawe\u0142 Ku\u017aniak","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Pawe\u0142 Ku\u017aniak","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/","url":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/","name":"Adding data from extension to iOS apps. How to do it? | Zaven Blog","isPartOf":{"@id":"https:\/\/zaven.co\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#primaryimage"},"image":{"@id":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#primaryimage"},"thumbnailUrl":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/ostatnia-ostatnia.jpg","datePublished":"2016-07-08T09:27:52+00:00","dateModified":"2025-04-08T17:55:20+00:00","author":{"@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/c29fc600e8bb0269e5390d84f114ac54"},"description":"Welcome to the last part of our tutorial: how to add extensions to iOS apps. We will learn how to add data using a service from extension to iOS apps.","breadcrumb":{"@id":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#primaryimage","url":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/ostatnia-ostatnia.jpg","contentUrl":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/07\/ostatnia-ostatnia.jpg","width":2131,"height":1223,"caption":"How to add extensions to iOS apps"},{"@type":"BreadcrumbList","@id":"https:\/\/zaven.co\/blog\/add-extensions-ios-apps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zaven.co\/blog\/"},{"@type":"ListItem","position":2,"name":"How to add extensions to iOS apps (part 4)"}]},{"@type":"WebSite","@id":"https:\/\/zaven.co\/blog\/#website","url":"https:\/\/zaven.co\/blog\/","name":"Zaven Blog","description":"Software development blog. Generative AI, web &amp; mobile applications.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zaven.co\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/c29fc600e8bb0269e5390d84f114ac54","name":"Pawe\u0142 Ku\u017aniak","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/18ab5ae9a3e0bf0aaec573b90bbf3ea8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/18ab5ae9a3e0bf0aaec573b90bbf3ea8?s=96&d=mm&r=g","caption":"Pawe\u0142 Ku\u017aniak"},"description":"Pawe\u0142 is technical analyst, developer and IT operations specialist at Zaven. He can solve a 3x3x3 Rubik's cube in a matter of seconds and you can find more complicated ones lying around on his desk (solved, obviously). His problem-solving attitude is reflected in his work, as he likes to keep himself busy with non-trivial puzzles.","sameAs":["https:\/\/www.linkedin.com\/in\/pawe-kuniak-a33735104"],"url":"https:\/\/zaven.co\/blog\/author\/pkuzniakzaven-pl\/"}]}},"_links":{"self":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/350","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/comments?post=350"}],"version-history":[{"count":44,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/350\/revisions"}],"predecessor-version":[{"id":69783,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/350\/revisions\/69783"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/media\/461"}],"wp:attachment":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/media?parent=350"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/categories?post=350"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/tags?post=350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}