A stand-alone Swift wrapper around the FileMaker XML Web publishing interface, enabling access to FileMaker servers.

Overview

Perfect - FileMaker Server Connector

Get Involed with Perfect!

Star Perfect On Github Stack Overflow Follow Perfect on Twitter Join the Perfect Slack

Swift 4.1 Platforms OS X | Linux License Apache PerfectlySoft Twitter Slack Status

This project provides access to FileMaker Server databases using the XML Web publishing interface.

This package builds with Swift Package Manager and is part of the Perfect project. It was written to be stand-alone and so does not need to be run as part of a Perfect server application.

Ensure you have installed and activated the latest Swift 4.1.1 tool chain.

Linux Build Notes

Ensure that you have installed curl and libxml2.

sudo apt-get install libcurl4-openssl-dev libxml2-dev

Building

Add this project as a dependency in your Package.swift file.

.package(url: "https://github.com/PerfectlySoft/Perfect-FileMaker.git", from: "3.0.0")

Examples

To utilize this package, import PerfectFileMaker.

List Available Databases

This snippet connects to the server and has it list all of the hosted databases.

let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.databaseNames {
	result in
	do {
		// Get the list of names
		let names = try result()
		for name in names {
			print("Got a database name \(name)")
		}
	} catch FMPError.serverError(let code, let msg) {
		print("Got a server error \(code) \(msg)")
	} catch let e {
		print("Got an unexpected error \(e)")
	}
}

List Available Layouts

List all of the layouts in a particular database.

let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.layoutNames(database: "FMServer_Sample") {
	result in
	guard let names = try? result() else {
		return // got an error
	}
	for name in names {
		print("Got a layout name \(name)")
	}
}

List Field On Layout

List all of the field names on a particular layout.

let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.layoutInfo(database: "FMServer_Sample", layout: "Task Details") {
	result in
	guard let layoutInfo = try? result() else {
		return // error
	}
	let fieldsByName = layoutInfo.fieldsByName
	for (name, value) in fieldsByName {
		print("Field \(name) = \(value)")
	}
}

Find All Records

Perform a findall and print all field names and values.

let query = FMPQuery(database: "FMServer_Sample", layout: "Task Details", action: .findAll)
let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.query(query) {
	result in
	guard let resultSet = try? result() else {
		return // error
	}
	let fields = resultSet.layoutInfo.fields
	let records = resultSet.records
	let recordCount = records.count
	for i in 0..<recordCount {
		let rec = records[i]
		for field in fields {
			switch field {
			case .fieldDefinition(let def):
				let fieldName = def.name
				if let fnd = rec.elements[fieldName], case .field(_, let fieldValue) = fnd {
					print("Normal field: \(fieldName) = \(fieldValue)")
				}
			case .relatedSetDefinition(let name, _):
				guard let fnd = rec.elements[name], case .relatedSet(_, let relatedRecs) = fnd else {
					continue
				}
				print("Relation: \(name)")
				for relatedRec in relatedRecs {
					for relatedRow in relatedRec.elements.values {
						if case .field(let fieldName, let fieldValue) = relatedRow {
							print("\tRelated field: \(fieldName) = \(fieldValue)")
						}
					}
				}
			}
		}
	}
}

Find All Records With Skip & Max

To add skip and max, the query above would be amended as follows:

// Skip two records and return a max of two records.
let query = FMPQuery(database: "FMServer_Sample", layout: "Task Details", action: .findAll)
	.skipRecords(2).maxRecords(2)
...

Find Records Where "Status" Is "In Progress"

Find all records where the field "Status" has the value of "In Progress".

let qfields = [FMPQueryFieldGroup(fields: [FMPQueryField(name: "Status", value: "In Progress")])]
let query = FMPQuery(database: "FMServer_Sample", layout: "Task Details", action: .find)
	.queryFields(qfields)
let fms = FileMakerServer(host: testHost, port: testPort, userName: testUserName, password: testPassword)
fms.query(query) {
	result in
	guard let resultSet = try? result() else {
		return // error
	}
	let fields = resultSet.layoutInfo.fields
	let records = resultSet.records
	let recordCount = records.count
	for i in 0..<recordCount {
		let rec = records[i]
		for field in fields {
			switch field {
			case .fieldDefinition(let def):
				let fieldName = def.name
				if let fnd = rec.elements[fieldName], case .field(_, let fieldValue) = fnd {
					print("Normal field: \(fieldName) = \(fieldValue)")
					if name == "Status", case .text(let tstStr) = fieldValue {
						print("Status == \(tstStr)")
					}
				}
			case .relatedSetDefinition(let name, _):
				guard let fnd = rec.elements[name], case .relatedSet(_, let relatedRecs) = fnd else {
					continue
				}
				print("Relation: \(name)")
				for relatedRec in relatedRecs {
					for relatedRow in relatedRec.elements.values {
						if case .field(let fieldName, let fieldValue) = relatedRow {
							print("\tRelated field: \(fieldName) = \(fieldValue)")
						}
					}
				}
			}
		}
	}
}
You might also like...
A MongoDB interface for Swift [Not under active development]

MongoDB #This library is no longer under active development. I highly recommend using the robust, pure-swift alternative MongoKitten. A Swift MongoDB

A practical interface to the Steamworks SDK using the Swift C++ importer

steamworks-swift A practical interface to the Steamworks SDK using the Swift C++ importer. Caveat Integrator: The Swift C++ importer is a chaotic scie

Modern interface to UserDefaults + Codable support
Modern interface to UserDefaults + Codable support

Default Modern interface to UserDefaults + Codable support What is Default? Default is a library that extends what UserDefaults can do by providing ex

Web server serving local files

swift-web A web server serving local static files. Installation Using Mint The easiest way to install swift-web is via mint. mint install adam-fowler/

CoreData/Realm sweet wrapper written in Swift
CoreData/Realm sweet wrapper written in Swift

What is SugarRecord? SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData in a much easier way. Than

A Swift wrapper for system shell over posix_spawn with search path and env support.

AuxiliaryExecute A Swift wrapper for system shell over posix_spawn with search path and env support. Usage import AuxiliaryExecute AuxiliaryExecute.l

A Swift wrapper for SQLite databases

Squeal, a Swift interface to SQLite Squeal provides access to SQLite databases in Swift. Its goal is to provide a simple and straight-forward base API

An Objective-C wrapper for RocksDB - A Persistent Key-Value Store for Flash and RAM Storage.

ObjectiveRocks ObjectiveRocks is an Objective-C wrapper of Facebook's RocksDB - A Persistent Key-Value Store for Flash and RAM Storage. Current RocksD

A lightweight wrapper over UserDefaults/NSUserDefaults with an additional layer of AES-256 encryption

SecureDefaults for iOS, macOS Requirements • Usage • Installation • Contributing • Acknowledgments • Contributing • Author • License SecureDefaults is

Comments
  • The code compiles using the examples using spm and MacOS X

    The code compiles using the examples using spm and MacOS X

    swift build && ./.build/x86_64-apple-macosx10.10/debug/PerfectTemplate

    I have tried just about all the examples on the page, however all of them behave exactly the same as typing: echo -n and hitting enter in the terminal. I know FileMaker is set up correctly as I can use both curl and FX.php against the FileMaker server.

    $ cat Sources/PerfectTemplate/main.swift
    import PerfectHTTP
    import PerfectHTTPServer
    import PerfectSMTP
    import PerfectFileMaker
    
    let fms = FileMakerServer( host: "127.0.0.1", port: 8180, userName: "username", password: "password" )
    
    print( fms )
    
    fms.layoutInfo( database: "db", layout: "layout {
    	result in
    	guard let layoutInfo = try? result() else {
                    print( "No result" )
    		return // error
    	}
    	let fieldsByName = layoutInfo.fieldsByName
    	for ( name, value ) in fieldsByName {
    		print( "Field \( name ) = \( value )" )
    	}
    }
    

    Building and running the code:

    $ swift build && ./.build/x86_64-apple-macosx10.10/debug/PerfectTemplate
    warning: PackageDescription API v3 is deprecated and will be removed in the future; used by package(s): libxml2
    Compile Swift Module 'PerfectTemplate' (1 sources)
    Linking ./.build/x86_64-apple-macosx10.10/debug/PerfectTemplate
    FileMakerServer(host: "filemaker.lan.domain.tld", port: 80, userName: "username", password: "password" )
    devMB15R:PerfectTemplate user$
    
    $ cat Package.swift
    // swift-tools-version:4.0
    
    import PackageDescription
    let projectName = "PerfectTemplate"
    let package    = Package(
    	name: projectName,
    	products: [
    		.executable(name: "PerfectTemplate", targets: ["PerfectTemplate"])
    	],
    	dependencies: [
    		.package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", from: "3.0.0" ),
    		.package(url: "https://github.com/PerfectlySoft/Perfect-FileMaker.git", from: "3.0.0" ),
    		.package(url: "https://github.com/PerfectlySoft/Perfect-SMTP.git", from: "3.0.0" ),
    	],
    	targets: [
    		.target( name: projectName,
         dependencies: [
           "PerfectHTTPServer",
           "PerfectSMTP",
           "PerfectFileMaker",
         ]
       )
    	]
    )
    

    also tried to set up netcat to no avail

    let fms = FileMakerServer( host: "127.0.0.1", port: 8180, userName: "username", password: "password" )
    

    And listening as below:

    nc -l -p 8180
    

    No output.

    If there was errors I could correct myself, when there is apathy I'm having a hard time.

    opened by TyrfingMjolnir 3
Owner
PerfectlySoft Inc.
Server-side Swift
PerfectlySoft Inc.
A stand-alone Swift wrapper around the MySQL client library, enabling access to MySQL servers.

Perfect - MySQL Connector This project provides a Swift wrapper around the MySQL client library, enabling access to MySQL database servers. This packa

PerfectlySoft Inc. 118 Jan 1, 2023
A stand-alone Swift wrapper around the libpq client library, enabling access to PostgreSQL servers.

Perfect - PostgreSQL Connector This project provides a Swift wrapper around the libpq client library, enabling access to PostgreSQL servers. This pack

PerfectlySoft Inc. 51 Nov 19, 2022
A stand-alone Swift wrapper around the SQLite 3 client library.

Perfect - SQLite Connector This project provides a Swift wrapper around the SQLite 3 library. This package builds with Swift Package Manager and is pa

PerfectlySoft Inc. 47 Nov 19, 2022
GraphQLite is a toolkit to work with GraphQL servers easily. It also provides several other features to make life easier during iOS application development.

What is this? GraphQLite is a toolkit to work with GraphQL servers easily. It also provides several other features to make life easier during iOS appl

Related Code 2.8k Jan 9, 2023
A Cocoa / Objective-C wrapper around SQLite

FMDB v2.7 This is an Objective-C wrapper around SQLite. The FMDB Mailing List: https://groups.google.com/group/fmdb Read the SQLite FAQ: https://www.s

August 13.7k Dec 28, 2022
🔥 🔥 🔥Support for ORM operation,Customize the PQL syntax for quick queries,Support dynamic query,Secure thread protection mechanism,Support native operation,Support for XML configuration operations,Support compression, backup, porting MySQL, SQL Server operation,Support transaction operations.

?? ?? ??Support for ORM operation,Customize the PQL syntax for quick queries,Support dynamic query,Secure thread protection mechanism,Support native operation,Support for XML configuration operations,Support compression, backup, porting MySQL, SQL Server operation,Support transaction operations.

null 60 Dec 12, 2022
Simplified access to Apple's CloudKit

EVCloudKitDao Discuss EVCloudKitDao : What is this With Apple CloudKit, you can focus on your client-side app development and let iCloud eliminate the

Edwin Vermeer 632 Dec 29, 2022
An alternative to Core Data for people who like having direct SQL access.

FCModel 2 An alternative to Core Data for people who like having direct SQL access. By Marco Arment. See the LICENSE file for license info (it's the M

null 1.7k Dec 28, 2022
Easy direct access to your database 🎯

OHMySQL ★★ Every star is appreciated! ★★ The library supports Objective-C and Swift, iOS and macOS. You can connect to your remote MySQL database usin

Oleg 210 Dec 28, 2022
iForage helps foragers to track and manage foraging spots around them using CloudKit

iForage CloudKit Preface To expand on what I've created here: https://github.com/LynchConnor/iForage, I initially developed the app using Firebase. Th

Connor Lynch 3 Jul 14, 2022