{"id":997,"url":"https://github.com/PerfectlySoft/Perfect-FileMaker","last_synced_at":"2025-07-30T20:30:39.087Z","repository":{"id":63920157,"uuid":"63823505","full_name":"PerfectlySoft/Perfect-FileMaker","owner":"PerfectlySoft","description":"A stand-alone Swift wrapper around the FileMaker XML Web publishing interface, enabling access to FileMaker servers.","archived":false,"fork":false,"pushed_at":"2019-01-09T13:05:17.000Z","size":39,"stargazers_count":34,"open_issues_count":1,"forks_count":9,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-07-26T14:51:42.747Z","etag":null,"topics":["database","filemaker","filemaker-servers","perfect","server-side-swift","swift"],"latest_commit_sha":null,"homepage":"https://www.perfect.org","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PerfectlySoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-21T00:21:22.000Z","updated_at":"2024-03-19T06:56:13.000Z","dependencies_parsed_at":"2023-01-14T14:00:32.701Z","dependency_job_id":null,"html_url":"https://github.com/PerfectlySoft/Perfect-FileMaker","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/PerfectlySoft/Perfect-FileMaker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectlySoft%2FPerfect-FileMaker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectlySoft%2FPerfect-FileMaker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectlySoft%2FPerfect-FileMaker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectlySoft%2FPerfect-FileMaker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PerfectlySoft","download_url":"https://codeload.github.com/PerfectlySoft/Perfect-FileMaker/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectlySoft%2FPerfect-FileMaker/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267935125,"owners_count":24168266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","filemaker","filemaker-servers","perfect","server-side-swift","swift"],"created_at":"2024-01-05T20:15:36.579Z","updated_at":"2025-07-30T20:30:39.020Z","avatar_url":"https://github.com/PerfectlySoft.png","language":"Swift","funding_links":[],"categories":["Database","Database Connectors"],"sub_categories":["Getting Started","FileMaker","Other free courses","Linter"],"readme":"# Perfect - FileMaker Server Connector\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"http://perfect.org/get-involved.html\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://perfect.org/assets/github/perfect_github_2_0_0.jpg\" alt=\"Get Involed with Perfect!\" width=\"854\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/PerfectlySoft/Perfect\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://www.perfect.org/github/Perfect_GH_button_1_Star.jpg\" alt=\"Star Perfect On Github\" /\u003e\n    \u003c/a\u003e  \n    \u003ca href=\"http://stackoverflow.com/questions/tagged/perfect\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://www.perfect.org/github/perfect_gh_button_2_SO.jpg\" alt=\"Stack Overflow\" /\u003e\n    \u003c/a\u003e  \n    \u003ca href=\"https://twitter.com/perfectlysoft\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://www.perfect.org/github/Perfect_GH_button_3_twit.jpg\" alt=\"Follow Perfect on Twitter\" /\u003e\n    \u003c/a\u003e  \n    \u003ca href=\"http://perfect.ly\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://www.perfect.org/github/Perfect_GH_button_4_slack.jpg\" alt=\"Join the Perfect Slack\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://developer.apple.com/swift/\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Swift-4.1-orange.svg?style=flat\" alt=\"Swift 4.1\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://developer.apple.com/swift/\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Platforms-OS%20X%20%7C%20Linux%20-lightgray.svg?style=flat\" alt=\"Platforms OS X | Linux\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://perfect.org/licensing.html\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/License-Apache-lightgrey.svg?style=flat\" alt=\"License Apache\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://twitter.com/PerfectlySoft\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Twitter-@PerfectlySoft-blue.svg?style=flat\" alt=\"PerfectlySoft Twitter\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://perfect.ly\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://perfect.ly/badge.svg\" alt=\"Slack Status\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nThis project provides access to FileMaker Server databases using the XML Web publishing interface.\n\nThis package builds with Swift Package Manager and is part of the [Perfect](https://github.com/PerfectlySoft/Perfect) project. It was written to be stand-alone and so does not need to be run as part of a Perfect server application.\n\nEnsure you have installed and activated the latest Swift 4.1.1 tool chain.\n\n## Linux Build Notes\n\nEnsure that you have installed curl and libxml2.\n\n```\nsudo apt-get install libcurl4-openssl-dev libxml2-dev\n```\n\n## Building\n\nAdd this project as a dependency in your Package.swift file.\n\n```\n.package(url: \"https://github.com/PerfectlySoft/Perfect-FileMaker.git\", from: \"3.0.0\")\n```\n\n## Examples\n\nTo utilize this package, ```import PerfectFileMaker```.\n\n### List Available Databases\n\nThis snippet connects to the server and has it list all of the hosted databases.\n\n```swift\nlet fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)\nfms.databaseNames {\n\tresult in\n\tdo {\n\t\t// Get the list of names\n\t\tlet names = try result()\n\t\tfor name in names {\n\t\t\tprint(\"Got a database name \\(name)\")\n\t\t}\n\t} catch FMPError.serverError(let code, let msg) {\n\t\tprint(\"Got a server error \\(code) \\(msg)\")\n\t} catch let e {\n\t\tprint(\"Got an unexpected error \\(e)\")\n\t}\n}\n```\n\n### List Available Layouts\n\nList all of the layouts in a particular database.\n\n```swift\nlet fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)\nfms.layoutNames(database: \"FMServer_Sample\") {\n\tresult in\n\tguard let names = try? result() else {\n\t\treturn // got an error\n\t}\n\tfor name in names {\n\t\tprint(\"Got a layout name \\(name)\")\n\t}\n}\n```\n\n### List Field On Layout\n\nList all of the field names on a particular layout.\n\n```swift\nlet fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)\nfms.layoutInfo(database: \"FMServer_Sample\", layout: \"Task Details\") {\n\tresult in\n\tguard let layoutInfo = try? result() else {\n\t\treturn // error\n\t}\n\tlet fieldsByName = layoutInfo.fieldsByName\n\tfor (name, value) in fieldsByName {\n\t\tprint(\"Field \\(name) = \\(value)\")\n\t}\n}\n```\n\n### Find All Records\n\nPerform a findall and print all field names and values.\n\n```swift\nlet query = FMPQuery(database: \"FMServer_Sample\", layout: \"Task Details\", action: .findAll)\nlet fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)\nfms.query(query) {\n\tresult in\n\tguard let resultSet = try? result() else {\n\t\treturn // error\n\t}\n\tlet fields = resultSet.layoutInfo.fields\n\tlet records = resultSet.records\n\tlet recordCount = records.count\n\tfor i in 0..\u003crecordCount {\n\t\tlet rec = records[i]\n\t\tfor field in fields {\n\t\t\tswitch field {\n\t\t\tcase .fieldDefinition(let def):\n\t\t\t\tlet fieldName = def.name\n\t\t\t\tif let fnd = rec.elements[fieldName], case .field(_, let fieldValue) = fnd {\n\t\t\t\t\tprint(\"Normal field: \\(fieldName) = \\(fieldValue)\")\n\t\t\t\t}\n\t\t\tcase .relatedSetDefinition(let name, _):\n\t\t\t\tguard let fnd = rec.elements[name], case .relatedSet(_, let relatedRecs) = fnd else {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tprint(\"Relation: \\(name)\")\n\t\t\t\tfor relatedRec in relatedRecs {\n\t\t\t\t\tfor relatedRow in relatedRec.elements.values {\n\t\t\t\t\t\tif case .field(let fieldName, let fieldValue) = relatedRow {\n\t\t\t\t\t\t\tprint(\"\\tRelated field: \\(fieldName) = \\(fieldValue)\")\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n### Find All Records With Skip \u0026amp; Max\n\nTo add skip and max, the query above would be amended as follows:\n\n```swift\n// Skip two records and return a max of two records.\nlet query = FMPQuery(database: \"FMServer_Sample\", layout: \"Task Details\", action: .findAll)\n\t.skipRecords(2).maxRecords(2)\n...\n```\n\n### Find Records Where \"Status\" Is \"In Progress\"\n\nFind all records where the field \"Status\" has the value of \"In Progress\".\n\n```swift\nlet qfields = [FMPQueryFieldGroup(fields: [FMPQueryField(name: \"Status\", value: \"In Progress\")])]\nlet query = FMPQuery(database: \"FMServer_Sample\", layout: \"Task Details\", action: .find)\n\t.queryFields(qfields)\nlet fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)\nfms.query(query) {\n\tresult in\n\tguard let resultSet = try? result() else {\n\t\treturn // error\n\t}\n\tlet fields = resultSet.layoutInfo.fields\n\tlet records = resultSet.records\n\tlet recordCount = records.count\n\tfor i in 0..\u003crecordCount {\n\t\tlet rec = records[i]\n\t\tfor field in fields {\n\t\t\tswitch field {\n\t\t\tcase .fieldDefinition(let def):\n\t\t\t\tlet fieldName = def.name\n\t\t\t\tif let fnd = rec.elements[fieldName], case .field(_, let fieldValue) = fnd {\n\t\t\t\t\tprint(\"Normal field: \\(fieldName) = \\(fieldValue)\")\n\t\t\t\t\tif name == \"Status\", case .text(let tstStr) = fieldValue {\n\t\t\t\t\t\tprint(\"Status == \\(tstStr)\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase .relatedSetDefinition(let name, _):\n\t\t\t\tguard let fnd = rec.elements[name], case .relatedSet(_, let relatedRecs) = fnd else {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tprint(\"Relation: \\(name)\")\n\t\t\t\tfor relatedRec in relatedRecs {\n\t\t\t\t\tfor relatedRow in relatedRec.elements.values {\n\t\t\t\t\t\tif case .field(let fieldName, let fieldValue) = relatedRow {\n\t\t\t\t\t\t\tprint(\"\\tRelated field: \\(fieldName) = \\(fieldValue)\")\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPerfectlySoft%2FPerfect-FileMaker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPerfectlySoft%2FPerfect-FileMaker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPerfectlySoft%2FPerfect-FileMaker/lists"}