{"id":9193,"date":"2022-02-23T22:30:36","date_gmt":"2022-02-23T22:30:36","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=9193"},"modified":"2022-02-23T22:36:25","modified_gmt":"2022-02-23T22:36:25","slug":"interacting-with-eureka-from-swift-5","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/interacting-with-eureka-from-swift-5\/","title":{"rendered":"Interacting with Eureka from Swift 5"},"content":{"rendered":"<p>I wanted to get my little Swift console application (developed in the post <a href=\"https:\/\/putridparrot.com\/blog\/creating-a-console-app-in-swift-on-linux\/\" rel=\"noopener\" target=\"_blank\">Creating a console app. in Swift (on Linux)<\/a>) working with Eureka. <\/p>\n<p>So in the last post I outlined the simple steps to get <a href=\"https:\/\/putridparrot.com\/blog\/eureka-in-docker\/\" rel=\"noopener\" target=\"_blank\">Eureka up and running in docker<\/a>. Now let&#8217;s combine these posts along with the information from my the post <a href=\"https:\/\/putridparrot.com\/blog\/interacting-with-eureka-via-its-rest-operations\/\" rel=\"noopener\" target=\"_blank\">Interacting with Eureka via it\u2019s REST operations<\/a> and create ourselves a Swift Eureka client.<\/p>\n<p><em>Before I get started, I have not found the generation of JSON from types or for that matter generating the Dictionary required for JSONSerialization as intuitive as C# (for example). I&#8217;m not sure if there&#8217;s a better way to do these things, but this code works so it&#8217;ll do for now. But if you know a better way please use it.<\/em><\/p>\n<p>To start with we&#8217;re just going to manually generate our JSON string to match the POST request that we need to tell EUREKA that our application is starting<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nlet json: String = &quot;{&quot; +\r\n  &quot;\\&quot;instance\\&quot;: {&quot; +\r\n    &quot;\\&quot;hostName\\&quot;: \\&quot;myhost\\&quot;,&quot; +\r\n    &quot;\\&quot;app\\&quot;: \\&quot;SWIFT-EUREKA\\&quot;,&quot; +\r\n    &quot;\\&quot;vipAddress\\&quot;: \\&quot;myservice\\&quot;,&quot; +\r\n    &quot;\\&quot;secureVipAddress\\&quot;: \\&quot;myservice\\&quot;,&quot; +\r\n    &quot;\\&quot;ipAddr\\&quot;: \\&quot;10.0.0.10\\&quot;,&quot; +\r\n    &quot;\\&quot;status\\&quot;: \\&quot;STARTING\\&quot;,&quot; +\r\n    &quot;\\&quot;port\\&quot;: {\\&quot;$\\&quot;: \\&quot;8080\\&quot;, \\&quot;@enabled\\&quot;: \\&quot;true\\&quot;},&quot; +\r\n    &quot;\\&quot;securePort\\&quot;: {\\&quot;$\\&quot;: \\&quot;8443\\&quot;, \\&quot;@enabled\\&quot;: \\&quot;true\\&quot;},&quot; +\r\n    &quot;\\&quot;healthCheckUrl\\&quot;: \\&quot;http:\/\/myservice:8080\/healthcheck\\&quot;,&quot; +\r\n    &quot;\\&quot;statusPageUrl\\&quot;: \\&quot;http:\/\/myservice:8080\/status\\&quot;,&quot; +\r\n    &quot;\\&quot;homePageUrl\\&quot;: \\&quot;http:\/\/myservice:8080\\&quot;,&quot; +\r\n    &quot;\\&quot;dataCenterInfo\\&quot;: {&quot; +\r\n      &quot;\\&quot;@class\\&quot;: \\&quot;com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo\\&quot;, &quot; +\r\n      &quot;\\&quot;name\\&quot;: \\&quot;MyOwn\\&quot;&quot; +\r\n    &quot;}&quot; +\r\n  &quot;}&quot; +\r\n&quot;}&quot;\r\n<\/pre>\n<p>Hopefully this is fairly obvious (even with all the escaping characters) what we&#8217;re doing, but to use this in JSONSerialization.data method is seems we need to convert this string to a Dictionary or Array, so here&#8217;s an extension method to convert to a dictionary<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nextension String {\r\n  func toDictionary() -&gt; &#x5B;String:AnyObject]? {\r\n    if let data = self.data(using: .utf8) {\r\n      return try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? &#x5B;String:AnyObject]\r\n    }\r\n    return nil\r\n  } \r\n}\r\n<\/pre>\n<p><em>There&#8217;s zero error handling here &#8211; I leave it to the reader to add that.<\/em><\/p>\n<p>So using the extension method <em>toDictionary<\/em> we&#8217;ll convert our JSON string into a dictionary which is then passed into the JSONSerialization.data to create a Data object, i.e.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nlet data = json.toDictionary()\r\nlet httpBody = try JSONSerialization.data(withJSONObject: data!, options: &#x5B;])\r\n<\/pre>\n<p>Now we&#8217;ll create the URL and URLRequest to call the Eureka service<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nlet url = URL(string: &quot;http:\/\/192.168.1.1:8761\/eureka\/apps\/swift-eureka&quot;)\r\nvar request = URLRequest(url: url!)\r\nrequest.httpMethod = &quot;POST&quot;\r\nrequest.setValue(&quot;application\/json&quot;, forHTTPHeaderField: &quot;Content-Type&quot;)\r\nrequest.setValue(&quot;application\/json&quot;, forHTTPHeaderField: &quot;Accept&quot;)\r\nrequest.httpBody = httpBody\r\nrequest.timeoutInterval = 20\r\n<\/pre>\n<p>The rest of the code is the same as <a href=\"https:\/\/putridparrot.com\/blog\/creating-a-console-app-in-swift-on-linux\/\" rel=\"noopener\" target=\"_blank\">Creating a console app. in Swift (on Linux)<\/a> but for completeness it&#8217;s list below in it&#8217;s entirety (don&#8217;t forget the extension method toDictionary is in some extension file).<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nimport Foundation\r\n#if canImport(FoundationNetworking)\r\nimport FoundationNetworking\r\n#endif\r\n\r\nlet session = URLSession.shared\r\nlet semaphore = DispatchSemaphore(value: 0)\r\n\r\nlet json: String = &quot;{&quot; +\r\n  &quot;\\&quot;instance\\&quot;: {&quot; +\r\n    &quot;\\&quot;hostName\\&quot;: \\&quot;myhost\\&quot;,&quot; +\r\n    &quot;\\&quot;app\\&quot;: \\&quot;SWIFT-EUREKA\\&quot;,&quot; +\r\n    &quot;\\&quot;vipAddress\\&quot;: \\&quot;myservice\\&quot;,&quot; +\r\n    &quot;\\&quot;secureVipAddress\\&quot;: \\&quot;myservice\\&quot;,&quot; +\r\n    &quot;\\&quot;ipAddr\\&quot;: \\&quot;10.0.0.10\\&quot;,&quot; +\r\n    &quot;\\&quot;status\\&quot;: \\&quot;DOWN\\&quot;,&quot; +\r\n    &quot;\\&quot;port\\&quot;: {\\&quot;$\\&quot;: \\&quot;8080\\&quot;, \\&quot;@enabled\\&quot;: \\&quot;true\\&quot;},&quot; +\r\n    &quot;\\&quot;securePort\\&quot;: {\\&quot;$\\&quot;: \\&quot;8443\\&quot;, \\&quot;@enabled\\&quot;: \\&quot;true\\&quot;},&quot; +\r\n    &quot;\\&quot;healthCheckUrl\\&quot;: \\&quot;http:\/\/myservice:8080\/healthcheck\\&quot;,&quot; +\r\n    &quot;\\&quot;statusPageUrl\\&quot;: \\&quot;http:\/\/myservice:8080\/status\\&quot;,&quot; +\r\n    &quot;\\&quot;homePageUrl\\&quot;: \\&quot;http:\/\/myservice:8080\\&quot;,&quot; +\r\n    &quot;\\&quot;dataCenterInfo\\&quot;: {&quot; +\r\n      &quot;\\&quot;@class\\&quot;: \\&quot;com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo\\&quot;, &quot; +\r\n      &quot;\\&quot;name\\&quot;: \\&quot;MyOwn\\&quot;&quot; +\r\n    &quot;}&quot; +\r\n  &quot;}&quot; +\r\n&quot;}&quot;\r\n\r\nlet data = json.toDictionary()\r\nlet httpBody = try? JSONSerialization.data(withJSONObject: data!, options: &#x5B;])\r\n\r\nlet url = URL(string: &quot;http:\/\/192.168.0.88:8761\/eureka\/apps\/swift-eureka&quot;)\r\nvar request = URLRequest(url: url!)\r\nrequest.httpMethod = &quot;POST&quot;\r\nrequest.setValue(&quot;application\/json&quot;, forHTTPHeaderField: &quot;Content-Type&quot;)\r\nrequest.setValue(&quot;application\/json&quot;, forHTTPHeaderField: &quot;Accept&quot;)\r\nrequest.httpBody = httpBody\r\nrequest.timeoutInterval = 20\r\n\r\nsession.dataTask(with: request) { (data, response, error) in\r\n    let result = String.init(data: data!, encoding: .utf8)\r\n    print(result!)\r\n    semaphore.signal()\r\n}.resume()\r\n\r\nsemaphore.wait()\r\n<\/pre>\n<p>At this time I haven&#8217;t got a great solution for using types to define our request as the request has some invalid name keys, such as $ and @enabled (again there may be a solution which I&#8217;ve not come across yet). To give the reader a starting point, here&#8217;s the code I have for turning my EurekaRequest type into a JSON string. <\/p>\n<p><em>I&#8217;ve not included the EurekaRequest so this really just shows a way to convert a type to a JSON string.<\/em><\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nlet instance = EurekaRequest()\r\nlet encoder = JSONEncoder();\r\n\/\/ required to stop \/\/ becoming \\\/\r\nencoder.outputFormatting = .withoutEscapingSlashes\r\nlet jsonData = try encoder.encode(instance)\r\n\r\n\/\/ convert to a string\r\nvar json = String(data: jsonData, encoding: String.Encoding.utf8)!;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I wanted to get my little Swift console application (developed in the post Creating a console app. in Swift (on Linux)) working with Eureka. So in the last post I outlined the simple steps to get Eureka up and running in docker. Now let&#8217;s combine these posts along with the information from my the post [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[240,286],"tags":[],"class_list":["post-9193","post","type-post","status-publish","format-standard","hentry","category-eureka","category-swift"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=9193"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9193\/revisions"}],"predecessor-version":[{"id":9201,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/9193\/revisions\/9201"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=9193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=9193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=9193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}