{"id":3251,"date":"2025-12-23T09:18:34","date_gmt":"2025-12-23T00:18:34","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=3251"},"modified":"2026-02-20T09:32:16","modified_gmt":"2026-02-20T00:32:16","slug":"swiftrandomuser","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2025\/12\/23\/swiftrandomuser\/","title":{"rendered":"[swift]RandomUser.me API"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb \uc544\ub798\ub294 RandomUser.me\uc758 API\ub97c \uc0ac\uc6a9\ud574\uc11c \uc720\uc800\ub97c \uc571\uc5d0\uc11c \ub79c\ub364\ud558\uac8c \ud638\ucd9c\ud558\ub294 \ub0b4\uc6a9\uc785\ub2c8\ub2e4.<br>Below is how to randomly call a user in your app using RandomUser.me&#8217;s API.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc11c\ubc84\ub97c \ub530\ub85c \uad6c\uc131\ud558\uc9c0\uc54a\uace0 api\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc571\uc744 \ub9cc\ub4e4\uc5b4 \ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>You can create an app using the API without configuring a separate server.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffbRandomUser.me Api<\/p>\n\n\n\n<p>\u2714\ufe0f \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c <a href=\"https:\/\/randomuser.me\/api\">https:\/\/randomuser.me\/api<\/a> \uc774\ub807\uac8c \uc2e4\ud589\uc2dc \uc0ac\uc6a9 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>You can use it by running https:\/\/randomuser.me\/api in your browser.<\/p>\n\n\n\n<p>\u2714\ufe0f \ub370\uc774\ud130\ub97c \uc0c8\ub86d\uac8c \uc694\uccad\uc2dc \ub79c\ub364\uc73c\ub85c \uc544\ub798\uc758 api\uc815\ubcf4\uac00 \ubc14\ub01d\ub2c8\ub2e4.<br>When you request new data, the API information below changes randomly.<\/p>\n\n\n\n<p>\u2b50\ufe0f \ucf54\ub4dc \uc124\uba85\uc740 \uc8fc\uc11d\uc744 \ucc38\uc870\ud558\uc2dc\uba74\ub429\ub2c8\ub2e4. \ucd94\uac00 \uc124\uba85\uc774 \ud544\uc694\ud558\uba74 \ub530\ub85c \ud3ec\uc2a4\ud305\ud558\uaca0\uc2b5\ub2c8\ub2e4.<br>Please refer to the comments for code explanations. If further explanation is needed, I will post it separately.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"results\": &#91;\n    {\n      \"gender\": \"female\",\n      \"name\": {\n        \"title\": \"Mrs\",\n        \"first\": \"Lisa\",\n        \"last\": \"Fowler\"\n      },\n      \"location\": {\n        \"street\": {\n          \"number\": 2580,\n          \"name\": \"Oaks Cross\"\n        },\n        \"city\": \"Armagh\",\n        \"state\": \"Highlands and Islands\",\n        \"country\": \"United Kingdom\",\n        \"postcode\": \"HH16 2NA\",\n        \"coordinates\": {\n          \"latitude\": \"-10.3689\",\n          \"longitude\": \"101.2611\"\n        },\n        \"timezone\": {\n          \"offset\": \"+5:00\",\n          \"description\": \"Ekaterinburg, Islamabad, Karachi, Tashkent\"\n        }\n      },\n      \"email\": \"lisa.fowler@example.com\",\n      \"login\": {\n        \"uuid\": \"a46a4808-b2fd-452b-b923-212f144a5349\",\n        \"username\": \"browndog164\",\n        \"password\": \"bones\",\n        \"salt\": \"k8ZwiUoK\",\n        \"md5\": \"bc71f9e4f2a4960d2e309be7b51c1f31\",\n        \"sha1\": \"ff2dde7c2e1d208e8ad05e06f5324d2d849fed0a\",\n        \"sha256\": \"ee02e23c14550ae433bf8052c1d7d23fb7cd8b4fd42cf10a0900ef3e6c9c4605\"\n      },\n      \"dob\": {\n        \"date\": \"1954-07-09T14:01:43.714Z\",\n        \"age\": 71\n      },\n      \"registered\": {\n        \"date\": \"2022-02-02T03:34:03.950Z\",\n        \"age\": 3\n      },\n      \"phone\": \"017687 96364\",\n      \"cell\": \"07149 397609\",\n      \"id\": {\n        \"name\": \"NINO\",\n        \"value\": \"LP 72 77 54 S\"\n      },\n      \"picture\": {\n        \"large\": \"https:\/\/randomuser.me\/api\/portraits\/women\/8.jpg\",\n        \"medium\": \"https:\/\/randomuser.me\/api\/portraits\/med\/women\/8.jpg\",\n        \"thumbnail\": \"https:\/\/randomuser.me\/api\/portraits\/thumb\/women\/8.jpg\"\n      },\n      \"nat\": \"GB\"\n    }\n  ],\n  \"info\": {\n    \"seed\": \"42e207ecbc7085df\",\n    \"results\": 1,\n    \"page\": 1,\n    \"version\": \"1.4\"\n  }\n}<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ucf54\ub4dc \/ Code<\/p>\n\n\n\n<p>\u2714\ufe0f ContentView.swift<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nimport SwiftUI\n\nstruct ContentView: View {\n    \n    \/\/ SwiftUI\ub294 \uc774 ViewModel \uc548\uc758 @Published \ud504\ub85c\ud37c\ud2f0(user, errorMessage)\uac00 \ubc14\ub00c\uba74\n    \/\/ \uc790\ub3d9\uc73c\ub85c \ubdf0\ub97c \ub2e4\uc2dc \uadf8\ub9ac\ub3c4\ub85d \ud568\n    \/\/ SwiftUI automatically redraws the view when the @Published properties (user, errorMessage) in this ViewModel change.\n    @StateObject private var viewModel = RandomUserViewModel()\n    \n    var body: some View {\n        VStack(spacing: 20) {\n            \n            \/\/ \ud504\ub85c\ud544 \/ Profile name\n            if let user = viewModel.user {\n                \/\/ \ud504\ub85c\ud544 \ub124\uc784 \/ profile name\n                Text(\"\\(user.name.first) \\(user.name.last)\")\n                    .font(.title)\n                \n                \/\/ \ud504\ub85c\ud544 \uc774\ubbf8\uc9c0 URL\uc774\ubbf8\uc9c0 \ube44\ub3d9\uae30 \ub85c\ub529\n                \/\/ Profile image URL image asynchronous loading\n                AsyncImage(url: URL(string: user.picture.large)) { image in\n                    image\n                        .resizable()\n                        .scaledToFit() \/\/ \ube44\uc728\uc720\uc9c0\ud558\uba70 \ub9de\ucda4 \/ Custom while maintaining proportions\n                        .frame(width: 180, height: 180)\n                        .clipShape(Circle())\n                } placeholder: {\n                    ProgressView() \/\/ \ub85c\ub529\uc911\uc5d0\ub294 ProgressView\ud45c\uc2dc \/ Display ProgressView while loading\n                }\n            }\n            \n            \/\/ \uc5d0\ub7ec \uba54\uc138\uc9c0 \/ error message\n            if let error = viewModel.errorMessage {\n                Text(\"Error: \\(error)\")\n                    .foregroundColor(.red)\n            }\n            \n            \/\/ \ubc84\ud2bc \/ button\n            Button(action: {\n                viewModel.fetchRandomUser()\n            }) {\n                Text(\"\ub79c\ub364 \uc720\uc800 \ubd88\ub7ec\uc624\uae30\/Load random users\")\n                    .padding()\n                    .background(Color.blue)\n                    .foregroundColor(.white)\n                    .cornerRadius(12)\n            }\n        }\n        .padding()\n    }\n}\n\n\n#Preview {\n    ContentView()\n}\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f RandomUserModel.swift<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import Foundation\n\n\/\/ Codable\uc744 \uc4f0\uba74 JSON \u2194 Struct \ubcc0\ud658\uc774 \uc790\ub3d9\n\/\/ If you use Codable, JSON \u2194 Struct conversion is automatic.\nstruct RandomUserResponse: Codable {\n    let results: &#91;RandomUser] \/\/ \"results\": &#91;\n}\n\nstruct RandomUser: Codable {\n    let name: Name            \/\/ \"results\": &#91; { \"name\": {\n    let picture: Picture\n    \n    struct Name: Codable {\n        let first: String     \/\/ \"results\": &#91; { \"name\": { \"first\": \"Lisa\",\"last\": \"Fowler\"\n        let last: String\n    }\n    \n    struct Picture: Codable {\n        let large: String\n    }\n}<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f RandomUserSwiftApp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import SwiftUI\n\n@main\nstruct RandomUserSwiftApp: App {\n    var body: some Scene {\n        WindowGroup {\n            ContentView()\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f RandomUserViewModel<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import Foundation\nimport Combine \/\/ add\n\nclass RandomUserViewModel: ObservableObject {\n    @Published var user: RandomUser?\n    @Published var errorMessage: String?\n    \n    private var cancellables = Set&lt;AnyCancellable&gt;()\n    \n    func fetchRandomUser() {\n        guard let url = URL(string: \"https:\/\/randomuser.me\/api\/\") else { return }\n        \n        \/*\n         Combine\uc758 Publisher \ud750\ub984\n         URLSession.shared.dataTaskPublisher(for: url)\n         \uae30\ubcf8\uc801\uc73c\ub85c \ubc31\uadf8\ub77c\uc6b4\ub4dc \uc2a4\ub808\ub4dc\uc5d0\uc11c \uc2e4\ud589\ub428\n         \ub124\ud2b8\uc6cc\ud06c \uc751\ub2f5, \ub370\uc774\ud130 \ub514\ucf54\ub529 \ub4f1\uc740 \ube44\ub3d9\uae30 \uc791\uc5c5\n         \uc774 \uc0c1\ud0dc\uc5d0\uc11c UI\ub97c \ubc14\ub85c \uc5c5\ub370\uc774\ud2b8\ud558\uba74 \ubb38\uc81c\uac00 \uc0dd\uae38 \uc218 \uc788\uc74c\n         \n         Combine's Publisher Flow\n         URLSession.shared.dataTaskPublisher(for: url)\n         By default, runs on a background thread.\n         Network responses, data decoding, etc. are asynchronous tasks.\n         Updating the UI immediately in this state can cause problems.\n         *\/\n        \n        URLSession.shared.dataTaskPublisher(for: url)\n            \/\/Publisher\uac00 (data: Data, response: URLResponse) \ud615\ud0dc\uc778\ub370 \uadf8\uc911 data\ub9cc \uc0ac\uc6a9\ud558\uaca0\ub2e4\ub294 \ub73b\n            \/\/Publisher is in the form of (data: Data, response: URLResponse), which means that only data will be used.\n            .map { $0.data }\n            \/\/ JSON \u2192 Swift Struct \ubcc0\ud658.\n            \/\/ Convert JSON \u2192 Swift Struct.\n            .decode(type: RandomUserResponse.self, decoder: JSONDecoder())\n            \/\/ UI \uc5c5\ub370\uc774\ud2b8\ub294 \ubc18\ub4dc\uc2dc \uba54\uc778 \uc2a4\ub808\ub4dc\uc5d0\uc11c \ud574\uc57c \ud558\uae30 \ub54c\ubb38\uc5d0 \uc774 \uc2dc\uc810(sink) \uc774\ud6c4 \ubaa8\ub4e0 downstream \uc791\uc5c5\uc744 \uba54\uc778 \uc2a4\ub808\ub4dc\uc5d0\uc11c \uc2e4\ud589.(\ubc31\uadf8\ub784\uc6b4\ub4dc \uc2a4\ub808\ub4dc\uc5d0\uc11c \uc2e4\ud589\uc2dc \ud06c\ub798\uc2dc \ubc1c\uc0dd\ud560 \uc218 \uc788\uc74c)\n            \/\/ Since UI updates must be done on the main thread, all downstream work after this point (sink) is executed on the main thread. (Crash may occur if executed on a background thread.)\n            .receive(on: DispatchQueue.main)\n            .sink(receiveCompletion: { completion in \/\/ \uad6c\ub3c5\uc2dc\uc791,\uc5d0\ub7ec\ucc98\ub9ac \/ Subscription start, error handling\n                switch completion {\n                case .finished:\n                    break\n                case .failure(let error):\n                    self.errorMessage = error.localizedDescription\n                }\n            }, receiveValue: { response in\n                \/\/ &lt;-- \uc5ec\uae30\uc11c \uc2e4\uc81c @Published user \ud504\ub85c\ud37c\ud2f0\uac00 \ubc14\ub01c(UI\uac31\uc2e0 \uc2dc\ud0a4\ub294 \uc704\uce58)\n                \/\/ &lt;-- Here, the actual @Published user property changes (where the UI is updated)\n                self.user = response.results.first\n            })\n            \/\/ \uad6c\ub3c5 \uc720\uc9c0\ud558\uae30 \uc704\ud574 \uc800\uc7a5 , inout\ud0a4\uc6cc\ub4dc in\uc740 \ud30c\ub77c\uba54\ud130\uc774\ub984(\ub808\uc774\ube14),.store\ud568\uc218\uac00 inout\ud0a4\uc6cc\ub4dc\ub97c \uc0ac\uc6a9\ud568\n            \/\/ To maintain subscription, store, inout keyword in is parameter name (label), .store function uses inout keyword\n            .store(in: &amp;cancellables)\n    }\n}<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc2a4\ud06c\ub9b0\uc0f7\/ScreenShot<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"[Swit]RandomUser API\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/SXKRgZpRWhw?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb \uc544\ub798\ub294 RandomUser.me\uc758 API\ub97c \uc0ac\uc6a9\ud574\uc11c \uc720\uc800\ub97c \uc571\uc5d0\uc11c \ub79c\ub364\ud558\uac8c \ud638\ucd9c\ud558\ub294 \ub0b4\uc6a9\uc785\ub2c8\ub2e4.Below is how to randomly call a user in your app using RandomUser.me&#8217;s API. \ud83d\udc49\ud83c\udffb \uc11c\ubc84\ub97c \ub530\ub85c \uad6c\uc131\ud558\uc9c0\uc54a\uace0 api\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc571\uc744 \ub9cc\ub4e4\uc5b4 \ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4.You can create an app using the API without configuring a separate server. \ud83d\udc49\ud83c\udffbRandomUser.me Api \u2714\ufe0f \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c https:\/\/randomuser.me\/api \uc774\ub807\uac8c \uc2e4\ud589\uc2dc \uc0ac\uc6a9 \ud560 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19,1],"tags":[],"class_list":["post-3251","post","type-post","status-publish","format-standard","hentry","category-swift","category-uncategorized","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/3251","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=3251"}],"version-history":[{"count":11,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/3251\/revisions"}],"predecessor-version":[{"id":3263,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/3251\/revisions\/3263"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=3251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=3251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=3251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}