{"id":156,"date":"2020-12-14T20:10:07","date_gmt":"2020-12-14T19:10:07","guid":{"rendered":"https:\/\/fred.appelman.net\/?p=156"},"modified":"2022-10-29T08:41:24","modified_gmt":"2022-10-29T06:41:24","slug":"integration-coreplot-in-swiftui-on-macos","status":"publish","type":"post","link":"https:\/\/fred.appelman.net\/?p=156","title":{"rendered":"Integration CorePlot in SwiftUI on MacOS"},"content":{"rendered":"<div class=\"entry\">\n<p>This walkthrough shows how to get an example application as present in the <a href=\"https:\/\/github.com\/core-plot\/core-plot\">core-plot<\/a><br \/>\nlibrary working using <tt>SwiftUI<\/tt> on MacOS.<\/p>\n<p>Although this example is done on the Mac, there is no reason to assume that the same process would not work for IOS.<\/p>\n<p><font color=\"blue\"><H1>1. Create the project<\/H1><\/font><\/p>\n<p>Select: <tt>File -> New -> Project...<\/tt><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/CreateProject.png\" alt=\"Create project\" title=\"CreateProject.png\" border=\"0\" width=\"599\" height=\"427\" \/><\/p>\n<p>Make certain that MacOS, App is selected and press Next.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/Select-Swift.png\" alt=\"Select Swift\" title=\"Select Swift.png\" border=\"0\" width=\"599\" height=\"427\" \/><\/p>\n<p>Make certain the interface is using SwiftUI and the language is Swift.<\/p>\n<p>Press next and save the project.<\/p>\n<p><font color=\"blue\"><H1>2. Integrate CorePlot<\/H1><\/font><\/p>\n<p>Select: <tt>File -> Add packages...<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/AddPackage-1.png\" alt=\"Add package\" title=\"AddPackage.png\" border=\"0\" width=\"599\" height=\"351\" \/><\/p>\n<p>Insert the proper URL in selection field.<\/p>\n<p>Select the branch <tt>release-2.4<\/tt>. The default master branch will not work, because it does not have support for the Swift Package<br \/>\nManager (SPM). Select <tt>Add Package<\/tt> and on the next screen select also <tt>Add Package<\/tt>.<\/p>\n<p>Just for testing run the application and you should see an hello world but this has nothing to do yet with CorePlot.<\/p>\n<p><font color=\"blue\"><H1>3. Create the CorePlot integration<\/H1><\/font><\/p>\n<p>Select File -> New -> File...<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/coreplot.png\" alt=\"Coreplot file\" title=\"coreplot.png\" border=\"0\" width=\"599\" height=\"427\" \/><\/p>\n<p>Make certain the MacOS and Swift File are selected.Select Next.<\/p>\n<p>Save the file under the name <tt>CorePlot.swift<\/tt><\/p>\n<p>The outline of the source code is as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/outline.png\" alt=\"Outline\" title=\"outline.png\" border=\"0\" width=\"600\" height=\"535\" \/><\/p>\n<ol>\n<li><tt>NSViewRepresentable<\/tt> is the glue that allows a non SwiftUI view to be used inside SwiftUI\n<li><tt>makeNSView<\/tt> is a mandatory method that creates the actual View. The code is coming mostly from the example <tt>DatePlot<\/tt> application.\n<li>The <tt>Coordinator<\/tt> is a class that can be used to manage the view as created in the previous step\n<li><tt>updateNSView()<\/tt> is a method that is called by SwiftUI whenever a change is detected. This method can apply those on the view.\n<li><tt>Coordinator<\/tt> is the manager of the CorePlot view. Note also that the coordinator functions as the DataSource for CorePlot\n<li><tt>External data is initialized when the <tt>CorePlot<\/tt> structure is initialized.\n<\/ol>\n<p><font color=\"blue\"><H2>3a. makeNSView(Context)<\/H2><\/font><\/p>\n<p>This is the definition of makeNSView:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/MakeNSView.png\" alt=\"makeNSView\" title=\"MakeNSView.png\" border=\"0\" width=\"590\" height=\"600\" \/><\/p>\n<p>The changes as compared to the <tt>awakeFromNib()<\/tt> from the demo application are as follows:<\/p>\n<ol>\n<li>The plotData is passed into the struct, hence it is not generated here.\n<li>The hostView is no longer optional since the view is generated here. So instead of passing the newGraph to the hostView, the newGraph is assigned to a newly generated CTPGraphHostingView.\n<li>The data source is not the struct itself, but instead the coordinator which is passed in the context.\n<li>The graph is not stored and the created hostview is returned.\n<\/ol>\n<p><font color=\"blue\"><H2>3b. makeCoordinator()<\/H2><\/font><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/MakeCoordinator.png\" alt=\"makeCoordinator\" title=\"MakeCoordinator.png\" border=\"0\" width=\"598\" height=\"87\" \/><\/p>\n<p>This is straight forward. The coordinator is passed self so that it can access the content of the CorePlot instance.<\/p>\n<p><font color=\"blue\"><H2>3c. updateNSView()<\/H2><\/font><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/updateNSView.png\" alt=\"updateNSView\" title=\"updateNSView.png\" border=\"0\" width=\"595\" height=\"109\" \/><\/p>\n<p>This method must be present to fulfil the protocol requirements. It is called when the view needs updating, hence the call to reloadData().<\/p>\n<p><font color=\"blue\"><H2>3d. Coordinator<\/H2><\/font><\/p>\n<p>The coordinator has no mandatory content.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/Coordinator.png\" alt=\"Coordinator\" title=\"Coordinator.png\" border=\"0\" width=\"599\" height=\"495\" \/><\/p>\n<p>In this implementation<\/p>\n<ol>\n<li>it has a reference to the CorePlot struct.\n<li>it implements the Data Source methods\n<\/ol>\n<p><font color=\"blue\"><H1>4. Use the new CorePlot view<\/H1><\/font><\/p>\n<p>Change the ContentView to look like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/ContentView.png\" alt=\"ContentView\" title=\"ContentView.png\" border=\"0\" width=\"573\" height=\"600\" \/><\/p>\n<ol>\n<li>A helper method to generate the test data\n<li>The instantiation of the CorePlot view. It must pass the mandatory plotData argument.\n<\/ol>\n<p><font color=\"blue\"><H1>5. Run<\/H1><\/font><\/p>\n<p>This now is a functioning application. Press run and see the result:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/fred.appelman.net\/wp-content\/uploads\/2022\/10\/running.png\" alt=\"View of running application\" title=\"running.png\" border=\"0\" width=\"600\" height=\"585\" \/><\/p>\n<p>The source of this project can be found on <a href=\"https:\/\/github.com\/fappelman\/SwiftUICorePlot-\">github<\/a>.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This walkthrough shows how to get an example application as present in the core-plot library working using SwiftUI on MacOS. Although this example is done on the Mac, there is no reason to assume that the same process would not work for IOS. 1. Create the project Select: File -> New -> Project&#8230; Make certain &#8230;<\/p>\n","protected":false},"author":1,"featured_media":173,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,15,10],"tags":[29,30,28],"class_list":{"0":"post-156","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-software","8":"category-spm","9":"category-swift","10":"tag-coreplot","11":"tag-macos","12":"tag-swiftui","13":"anons"},"_links":{"self":[{"href":"https:\/\/fred.appelman.net\/index.php?rest_route=\/wp\/v2\/posts\/156","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fred.appelman.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fred.appelman.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fred.appelman.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fred.appelman.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=156"}],"version-history":[{"count":7,"href":"https:\/\/fred.appelman.net\/index.php?rest_route=\/wp\/v2\/posts\/156\/revisions"}],"predecessor-version":[{"id":186,"href":"https:\/\/fred.appelman.net\/index.php?rest_route=\/wp\/v2\/posts\/156\/revisions\/186"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fred.appelman.net\/index.php?rest_route=\/wp\/v2\/media\/173"}],"wp:attachment":[{"href":"https:\/\/fred.appelman.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fred.appelman.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fred.appelman.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}