Blog  |  Support  |  Forums

Search Results for 'ssl'

Viewing 15 results - 46 through 60 (of 140 total)
  • Author
    Search Results
  • #36770

    In reply to: IP adress changes

    Sam Moffatt
    Participant

    The simplest solution is to figure out your networks DHCP range and then set your Mac to use a static IP address in System Preferences. This works if you have a Mac that is always at home like an iMac, Mac Mini or Mac Pro but won’t work with a laptop you take out into the world. It depends on your router configuration but there is generally some space that isn’t assigned to DHCP that you can use. You can typically figure it out if your router is something like 192.168.0.1 but all of your computers have IP addresses like 192.168.0.100 or higher. Ideally the router will tell you what range it uses and then you can go into System Preferences -> Network -> the network connection -> Advanced -> TCP/IP -> “Configure IPv4”: “Using DHCP with manual address” then you can set the IPv4 address manually to a static address that won’t change. If you have a static Mac deployment that is setup as a server and network configuration that doesn’t change then this will work fine.

    If that doesn’t work or isn’t an option for you, the other way would be to use Bonjour/mDNS to configure each of the clients. This will be a DNS name along the lines of “xyzmacname.local” or what ever you see in the “Sharing” network preference where it says “Computers on your local network can access your computer at:”. When you do this however, iOS will require that the connection is encrypted. iOS only allows unencrypted connections to IP addresses, so you need to go through the CouchDB guide to set up SSL. Once you do this then you can use the DNS name on all of your clients and when the IP address changes, they should work (might be a bit of a delay between picking up the change). Checkout the Tap Forms manual for the SSL instructions and also if you do a search on the forum you’ll find a bunch of other posts on SSL setup.

    If you have autosync enabled in the sync preferences for the document, the sync button likely won’t do much because you’re already sync’d. If you don’t have autosync enabled and everything is otherwise working, that will force a sync to happen. If there is a connectivity or an error then I think there are certain situations where it doesn’t work properly because the internal sync client has decided it can’t work (too many failures). If I suspect things aren’t working properly, I usually go into the sync preferences and click logout and login again because if something is wonky it resets all of the state from scratch.

    #36750
    john cesta
    Participant

    I agree on the pick list thing and I use this method for other things, certainly works great.

    But with my brain and the importance of the prospects and not forgetting about them or mistagging them etc I need to have them in a separate standout form for quick easy simplified access.

    The way I have it now is ok and it’s not a big hassle to move them over but I think I’ll take the challenge and try and create a script to copy them over.

    Attachments:
    You must be logged in to view attached files.
    #36322
    Karl M. Rowe
    Participant

    “The four ‘Over-15’ checked checkboxes would be noted and the first four of the first set of checkboxes would then be checked. I would love to be able to automate these two functions with a script.”

    I’m sorry; the items that correspond to the first 15 checkboxes as well as four checkboxes in the “Over-15” checkboxes are the number of items purchased during a calendar month by the customer. I had tossed out 19 items as an example without explaining why 19. If the customer were to have purchased 19 items during the month, this would be recorded in the database by making sure that all 15 of the checkboxes in the first set are checked, and making sure that four of the ten “Over-15” checkboxes in the second set would be checked.

    A search of the database for all records containing a “Yes” at the end of a month would include this record, indicating that this customer is entitled to a free item, but the 15 checkboxes of this record and all other “Yes” records would then need to be reset (so I would definitely have a use for the script you provided to reset these checkboxes!). This means that for each “Yes” record, I would do such a reset and then use the number in the database that indicates the total number of “Over-15” checkboxes checked—in the case of this record that number is “4”—to set four of the 15 checkboxes just reset and then reset the “Over-15” checkboxes (using a similar script to reset all ten checkboxes).

    The database is ready to record subsequent purchases made, which would entitle this same customer to another free item should she purchase an additional 11 items during the following month. I realize this explanation was needlessly verbose, but I rushed this post. I’ll read it layer, but I hope you should get the drift.

    Peace

    #36182
    Guillaume Kuster
    Participant

    I switched to CouchDB yesterday, hosted on a vps I already had. Seems solid so far in my testing, but so did iCloud in the beginning. Time will tell.

    CouchDB is way, way faster indeed to sync but definitely not “Grandma collecting recipies” simple.

    I had to build it from source as apt failed to install CouchDB on my debian 9.9 server. Also, getting SSL to work requires some testing. Following Brendan’s instructions works fine on Macs, but not on iOS devices anymore as the self-signed certificate .crt generated on the server (and then airdropped to the iOS device and installed) would not appear on iOS devices under the Enable Full Trust For Root certificates under Settings > General > About > Certificate Trust Settings. So here’s what worked for me:

    – generate a certificate as stated here
    – once you CouchDB server is correctly configured for SSL and restarted, use your Mac browser to try to connect to https://<Your Server>:6984/_utils/index.html
    – your browser will display an alert saying that the SSL certificate of this website is not valid. Click through the link to visit anyway and type your session password to trust the certificate. This will store your .crt certificate in your Keychain.
    – open you Keychain and locate the previously accepted certificate (searching for the IP address) and export it
    – Airdrop this certificate to your iOS device(s) and install it. It will appear under the Enable Full Trust For Root certificates under Settings > General > About > Certificate Trust Settings as a switch. Enable it and Tap Forms will accept to sync via CouchDB using an URL in the format https://<Your Server>:6984 with your user name and password.

    And as a side note: sync with CloudDB doesn’t work great on my iOS 13 beta iPad (build 17A5534f) but that’s of course not a problem for the moment. The behaviour is as follows: where every change made everywhere else (Phone or either of my macs) are synced in seconds on all other machines, the iPad would lag behind and sometimes never sync. Changed made on the iPad would generally but not always sync to other machines, changes made on other machines would rarely sync to the iPad.

    #36120
    Sam Moffatt
    Participant

    Is privacy and security the main reason for choosing CouchDB over iCloud?
    Do you recommend downloading the iOS version in the beginning or after you have all your forms build? What determines that decision?

    I started using Tap Forms with version 3 and followed the upgrade to 5. Version 3 did a lot of what I cared about and used iCloud to sync all of the documents around. iCloud was really slow with some of my attachment heavy documents (my main document is 6GB) which meant sync took forever to run and bulk changes even longer. I have an iMac at home that I set up essentially as a server using the P2P sync and then once CouchDB was added it became the CouchDB host. CouchDB gives me access to the innards of my TapForms documents to do interesting stuff like build a tree of my database structure, build my own more fine grained backup tooling and to integrate with tools like ElasticSearch and Kibana to do some graphing of the data.

    I had TapForms on both iOS and Mac at that point to replace a Bento based workflow and I think it’s been a great shift (except for layouts, Bento had iOS layouts which helps it there). I generally develop new forms on the Mac and then push them from there but I’m not afraid of building stuff on the fly on my phone too. You can build everything as you go and it’ll sync the structure to all of the devices.

    Are there a lot of differences in syntax between the Mac and iOS versions and do they work seamlessly with each other despite those differences?

    The two versions offer almost all of the same features, the only missing one on iOS is custom layouts. There are different user interactions that can make things a little more tedious on iOS but a lot of that is due to the smaller form factor. I’m sure there are a few other things missing but most of the time I don’t miss them (except for the oft requested custom layouts, which to get right on iOS will be a chunk of work as Bento only had custom layouts on iPad, not iPhone).

    Let’s talk form building and linking strategy for a minute. If you have a main topic, we’ll use medicinal herbs for example, :)

    I want to track: Broad categories and intricate details about each herb.

    1. History of each:
    Acquired it: When, where who from, how and why acquired: Grew it, Bought it, Wildcrafted it.
    Positive identification attributes of each herb.
    2. Culinary Information
    a. Edible parts
    b. Various possible preparations
    c. Nutritional information
    d. Recipes

    3. Growing Information for each herb, both recommended and actual and success rate of each method.

    4. Medicinal Information: Properties, Actions, Constituents, Various medicinal preparation possibilities .

    5. Work in Progress- Start, Strain, Bottle, Label, and Store

    6. Expenses: Assets, Supplies (consumable, Functional, Packaging)

    7. Inventory:
    Location,
    Container size and date,
    Amount on hand,
    Age and expiration date
    Consumable Supplies
    Macerating
    Ability to increase and decrease amount in each, broken down by preparation type:
    Tinctures,
    Infused Oils,
    Vinegars,
    Macerating
    Consumable Supplies,

    Looks like you’re well on your way to a database structure already :)

    My spreadsheets have become too long, too many, too time consuming and too redundant and added to that using Quicken to manage the expenses. So the broad end goal here is to greatly reduce the paperwork time and organization of it all by entering each piece of information about each herb ONCE and being able to, at a click, see any individual piece of information or all the information about a particular herb.

    What you’re looking for here is generally referred to as “third normal form” for a database. There are a few guides out there that explain it but functionally the idea is that you identify as precise a subset of the data and then give it a key. In TapForms, each record has it’s own generated key which you can then use to link.

    As far as data entry for new records goes, the more input boxes where necessary, multiple choice check boxes and radio buttons where possible and branching decisions via IF, Then, Else statements seems logical to me but I have no experience with databases so I am open to suggestions.

    That being said, design-wise, Is it better to have more or fewer forms?

    The determination I’d go with is what unique details does this form capture. I started off in Bento with a “Purchases” form that stored a bunch of details about the purchases I make and image attachments for reference. Within TapForms I’ve now morphed that into a much larger structure with a form that stores unique “Order” details (when purchased, where, how much, tax, discounts, etc), a line item “Order Item” form which then links back to my more detail orientated “Purchases” form. I also have “Shipments” which are linked from “Orders” and also “Purchases” because an order can have multiple shipments so all of those shipments are linked to the order and I sometimes link the individual purchases to shipments when orders are split shipped.

    Design wise you follow third normal form to reduce each form to it’s unique items and progress from there. As you can likely tell, I’ve done that progressively over time and I use the increasing amounts of automation in TapForms to be able to make some of that quicker whilst maintaining my legacy “Purchases” structure as well.

    For the forms that I do create, (all information revolving around each individual herb), should they all have a one to many link with inverse relationship checked? Or say, in the case of storage location and growing conditions, since they all have them, be linked as many to many? I am unclear as to what determinations to consider in the design phase. Is that determined by how you want to view the end results?

    When I look at my Purchases based document, I have two entry points: one from Orders and one from Purchases. Purchases is a relatively “flat” document with a lot of duplicated fields whilst “Orders” has what I started off as more normalised. Orders -> Order Items is 1:M, Order Items -> Purchases is M:M however I do some tricks. I use a calculation field to generate a composite key called “Purchase Key” that combines Marketplace, Store Name and Order ID which is in both “Orders” and “Purchases” which is used by a Link to Form JOIN field to link Purchases directly to Orders automatically as well. I didn’t build all of this in a day, it’s been evolving over years to get to where it is today. Just make sure you do a backup before majorly restructuring your database and also disable sync to prevent the changes propagating as you make them.

    Ideally, I imagine an opening screen asking me which herb I want to work with and letting me choose either from a list of Common name OR Latin name.

    Your entry point would be the herb names in those two forms, that’s your first document. Then you link to form into the rest of the data structures.

    Once chosen, it would ask me what a I want to do with the herb and show me the following choices:

    Acquire it,
    Grow it
    Process it – Dry it , Freeze it, Package it or Store it
    Work in Progress
    Start a Preparation –
    Strain a Preparation
    Build a value added product
    Research it
    Count it
    Find it – Finished product in storage or Macerating
    View Logs
    Daily Log
    Individual herb log
    Herb Identity Checklist

    Once chosen then launch into each aspect of those categories and store any input information in a record under that herb.

    Those mostly map into forms that makes sense. Acquire sounds like a form about where you got the herb, Grow it similarly. Preparations is a single form with some filters as is your logs (which I suspect is the original use case). You can use prompter to provide simpler UI interactions or you can just use links.

    Then there is the question of importing the past 8 years of data. Should I arrange the spreadsheet columns to match the new data records tables or design the new data entry to match the spreadsheet columns?

    Thoughts?

    This is actually the truly hard question of the lot because you only make this decision once. The rest you can evolve over time to add new fields, new forms, new links, etc. This one is truly a one time decision.

    The advantage of creating your TapForms structures to replicate your spreadsheets is that you might be able to continue to use TapForms in a not dissimilar way to how you use your spreadsheets today. That means you can leverage slightly more structured data entry to start getting everything better from a structure you know already. The disadvantage here is that you’ve likely got some amount of duplication in place today and this propagates it (not dissimilar to my own “Purchases” form). If you’re using any sort of automation, macros or formula in your spreadsheets then those would also need to be ported across before you can be fully productive. The other advantage of keeping it 1:1 early on is if you decide that TapForms isn’t the answer, then exporting the data back out again and reintegrating it into your spreadsheets will be easier.

    The advantage of building everything brand new in TapForms would be the ability to design out your structure in third normal form and have everything set up right from the beginning. You already have a strong idea of your data model (it’s there in your spreadsheet), you just need to go through and figure out the unique items that are duplicated and turn them into forms. The downside of this is that your spreadsheets aren’t in this format and to import your data will require a lot of massaging to get that to work. Instead of taking what you already have and immediately mapping it across and then going through to validate that all of the data loaded into TapForms correctly using it’s built in table view, you’re going to have to do that twice: once when converting your sheets into a form TapForms can import and a second time when you import it into TapForms. As with any data conversion activity, you want to make sure that you’ve got everything moved across accurately and the only way to trust that is to verify the transformed data. If you find records or entries in the first situation that got broken in transit, then it’s a 1:1 mapping to fix whilst if you find records mismatched here, you have to do the normalisation yourself.

    My leaning would be recreate the data in TapForms aligned to your current structure and then start to use the TapForms functionality to progressively make it better. Thinking back to my own “Orders” -> “Order Items” -> “Purchases” use case, I have a script in “Order Items” that takes the current record, looks up it’s parent “Orders” record and uses data in both of those to create a new “Purchases” record. Make sure you keep backups (TapForms makes it easy) and just progressively improve your data structure.

    Here’s the meat of the script that takes order items/orders and makes a new purchases record:

    function createDetailRecord()
    {
    	// The order ID linking field.
    	var order_id_fld = 'fld-c3a6725d7d9446da92bbb880ffe90a9e';
    
    	// Get the parent order field.
    	var order = record.getFieldValue(order_id_fld);
    
    	// Pull some details from this record (order item)
    	var title = record.getFieldValue('fld-39ca9564ef2347ac93f933bc9a2316ac');
    	var price = record.getFieldValue('fld-a2973999a60d4319baf0b4480d6f57a0');
    	var note = record.getFieldValue('fld-d0cfab9ec09d497294fbd8b5b52caf16');
    	var line_number = record.getFieldValue('fld-f95b68d488cb4b058bbf3de84e1a7c3b');
    
    	// Pull some other values across.
    	var purchase_date = order.getFieldValue('fld-bc2e4b152dee42ac9361539a6e37cb5d');
    	var marketplace = order.getFieldValue('fld-fa37906add2942c88bce3b500561c42d');
    	var order_id = order.getFieldValue('fld-8228040b4641449b96aabfaea15f1ac5');
    	var store_name = order.getFieldValue('fld-c153da2f9a504be4b6fee4b5b62a1c11');
    	var ship_date = order.getFieldValue('fld-6ab700ccc11d418fbd27d8899d00c7a9');
    	var delivery_date = order.getFieldValue('fld-4b1c4180dc1b4bb08b32d16fa60cae66');
    	var purchase_key = order.getFieldValue('fld-3e49aaa5bc32429c8f0f0f234878356d');
    
    	// Do something
    	// Details field names
    	var details_title_id = 'fld-0d0edd2552ea461e929f806a4e5552b5';
    	var details_price_id = 'fld-08129d71ab0f4fa4a2749456281fca07';
    	var details_notes_id = 'fld-bf19d52c18cb4f5198df191ef7902e1b';
    
    	var details_purchase_date_id = 'fld-ccbd9a8f51d34246bebfb31aa4e397dd';
    	var details_ship_date_id = 'fld-cb3a9886ac7f4ec487447801a3911a1a';
    	var details_received_date_id = 'fld-bb17d48e41c7423692ab586f6c884d05';
    
    	var details_order_id_id = 'fld-e3e66a0f2e5c4df7b9496f65355e0bcf';
    	var details_marketplace_id = 'fld-c163aba17ae64c4d93b5a53819a139dc';
    	var details_store_name_id = 'fld-3d98dc6cdcae4a88909c97c80dde7bfb';
    
    	var details_state_id = 'fld-9402f8c0d53c43b986fee4ebc3468929';
    
    	var details_shipping_tracking_number_id = 'fld-6ea45a9c141343628940bfbcfa38ee90';
    	var details_shipping_carrier_id = 'fld-12644a7a4ae24ed8a7926123832d3557';
    	
    	var details_purchase_key_id = 'fld-8be9b2c2603f458f8349082237c41964';
    	var details_order_line_number_id = 'fld-da763fa0946d4be79039b4e828cf85f4';
    
    	var data = {
    		// Order Item Details
    		[details_title_id]: title,
    		[details_price_id]: price,
    		[details_notes_id]: note,
    		[details_order_line_number_id]: line_number,
    		
    		// Order Details
    		[details_purchase_date_id]: purchase_date,
    		[details_ship_date_id]: ship_date,
    		[details_received_date_id]: delivery_date,
    		[details_order_id_id]: order_id,
    		[details_marketplace_id]: marketplace,
    		[details_store_name_id]: store_name,
    		[details_purchase_key_id]: purchase_key,
    	};
    
    	// If there is a delivery date, state is delivered.
    	if (delivery_date)
    	{
    		data[details_state_id] = "Delivered";
    	}
    	// If there is a ship date, state is shipped.
    	else if (ship_date)
    	{
    		data[details_state_id] = "Shipped";
    	}
    	// If we have no ship or delivery dates then it's purchased
    	else
    	{
    		data[details_state_id] = "Purchased";
    	}
    
    	var order_shipments_link = 'fld-db2fcdb4d79c466ea09671c47d2ae645';
    	var order_shipments_records = order.getFieldValue(order_shipments_link);
    
    	var shipments_tracking_number_id = 'fld-c487390743c947969cbe661cff596855';
    	var shipments_carrier_id = 'fld-0950c430cb0c41f79c51d43a544b366b';
    
    	var shipping_tracking_number = '';
    	var shipping_carrier = '';
    
    	for (var index = 0, count = order_shipments_records.length; index < count; index++)
    	{
    		if (shipping_tracking_number.length > 0)
    		{
    			shipping_tracking_number += " ";
    		}
    		
    		if (shipping_carrier.length > 0)
    		{
    			shipping_carrier += " ";
    		}
    	     
    	    shipping_tracking_number += order_shipments_records[index].getFieldValue(shipments_tracking_number_id);
    	    shipping_carrier += order_shipments_records[index].getFieldValue(shipments_carrier_id);
    	}
    
    	data[details_shipping_tracking_number_id] = shipping_tracking_number;
    	data[details_shipping_carrier_id] = shipping_carrier;
    
    	console.log(JSON.stringify(data));
    
    	// Last but not least push the new record.
    	var details_id = 'fld-ac04de32d98242b88333977c89526fc1';
    	var detailsRecord = record.addNewRecordToField(details_id);
    	detailsRecord.setFieldValues(data);
    	document.saveAllChanges();
    
    	return "Created child record for " + title;
    }

    And here’s the full document structure (using the build tree script) of my purchases document:

    Purchases: (frm-efc0199a2b1543f79e722383014533b0)
    	'Image 01' photo (fld-e631165b67374734a3b8f384708b5922)
    	'Title' text (fld-0d0edd2552ea461e929f806a4e5552b5)
    	'Subtitle' calc (fld-45ef928f87e24bcd93e6751c8c21a6cb)
    		Referenced Fields: 
    		 - State (fld-9402f8c0d53c43b986fee4ebc3468929)
    		 - Colour (fld-a8626656cc90455ea9336dd2488d4aef)
    		 - Category (fld-6fdd09891a8c4d73be1b24aa07d077be)
    	'State' text (fld-9402f8c0d53c43b986fee4ebc3468929)
    	'Previous State' text (fld-636a7a4671c14877b1b17ea1b579cef5)
    	'State Watcher' script (fld-45463af0b409465ea78ad7c498ee896d)
    	'Colour' text (fld-a8626656cc90455ea9336dd2488d4aef)
    	'Category' text (fld-6fdd09891a8c4d73be1b24aa07d077be)
    
    	=== 'Main' section (fld-76597ce17f924c25bbcb195df984331c) ===
    	'Date Created' date_created (fld-0d049abe706b41afb680ab9a1bf99d46)
    	'Date Modified' date_modified (fld-59a06347614e48e8bf547a855b781582)
    	'Purchase Date' date (fld-ccbd9a8f51d34246bebfb31aa4e397dd)
    	'Ship Date' date (fld-cb3a9886ac7f4ec487447801a3911a1a)
    	'Received Date' date (fld-bb17d48e41c7423692ab586f6c884d05)
    	'Last Worn' date (fld-c275ddef83824707b5fcccb5e0698768)
    	'Order ID' text (fld-e3e66a0f2e5c4df7b9496f65355e0bcf)
    	'Marketplace' text (fld-c163aba17ae64c4d93b5a53819a139dc)
    	'Store Name' text (fld-3d98dc6cdcae4a88909c97c80dde7bfb)
    	'Brand' text (fld-1e250019d7b249f282cc572814d3e71d)
    	'Source' web_site (fld-da9d866bf3ca4d47aade04a77efd7301)
    	'Source Scraper Script' script (fld-429e3e7ca20a49d38b26417e25e6db26)
    	'Item Key' text (fld-ae7379d699e9473aa2ab16a2a2f002d4)
    	'Price' number (fld-08129d71ab0f4fa4a2749456281fca07)
    	'Shipping Tracking Number' text (fld-6ea45a9c141343628940bfbcfa38ee90)
    	'Shipping Carrier' text (fld-12644a7a4ae24ed8a7926123832d3557)
    
    	=== 'Storage' section (fld-f99f779335f54b9cb0a4179a90bb97dd) ===
    	'Bag Barcode' text (fld-32d459f0b5fb4dc4974795c484832af1)
    	'Storage Box' text (fld-c08e3a9eb7784d7f8ee3a5576c0adffa)
    	'Attributes JSON' text (fld-f95fdbc7b2de4b6e8c3efb46c4c5452b)
    
    	=== 'Product Data' section (fld-5a42b3a215d947399c120078ea868672) ===
    	'Seller Category' text (fld-c89e0cb1479e4aa7bace4532320ab697)
    	'Title (Native)' text (fld-7b07b948fcee448daa06c41759e60233)
    	'Notes' note (fld-bf19d52c18cb4f5198df191ef7902e1b)
    	'Note Parser Script' script (fld-7ad209e1e70a4d53985fd229d122bcfd)
    	'Product Details' note (fld-f4e804c1869740a4bfd99a9adcfb3c49)
    	'Attributes' table (fld-6b2e26f53e6c4f0fb7ebc14400b4f118)
    		- 'Key' text (fld-1ff8c9d03e5e48beac09bdf639c0b286)
    		- 'Value' text (fld-6a145374b8774cfca13fdc0c1756d00f)
    		- 'Date Created' date_created (fld-ff31511cb4f54ce1b9f7ba85a8c0f43f)
    	'Attributes Extractor Script' script (fld-134d8663f295429e8e671e4e445e16d2)
    	'Variant Data' table (fld-eb212e705eb34e9ea5cc4386ea7a9b1f)
    		- 'Date Created' date_created (fld-482c2129901640299867923ced44ea01)
    		- 'Value' text (fld-e4ce093c1c22416192eb80554272d6cd)
    		- 'Key' text (fld-ecc1b1ede8414912a63ec144012fa9e9)
    	'Features' table (fld-1c20f096120845d98c2be64d2102c135)
    		- 'Feature Name' text (fld-0a478f6fce164226afab62946a3cec96)
    		- 'Feature Type' text (fld-84bd72ca7f354f8db68d469c427c25d0)
    
    	=== 'Attachments and Relationships' section (fld-339f3e44f6f142ddb5ceb1df699f494d) ===
    	'File Attachment' file (fld-c28b98cb3d8a43f98ee65503b30a6658)
    	'Order Items' from_form (fld-4862767002cf4aadad853e78dffb2eed) manyToMany 'Order Items' (frm-7a809372942a4031ae4bdf014f69e99b)
    	'Gallery' from_form (fld-41cea237bfa44135a788d09b2a390019) manyToMany 'Gallery Items' (frm-1dd95cbe70cc490c972487920317620c)
    	'Purchases' form (fld-2dfc5804be564f17bcc3c66fd1080121) manyToMany 'Purchases' (frm-efc0199a2b1543f79e722383014533b0)
    	'Shipments' form (fld-263993691f544158a16dd13fdf633562) manyToMany 'Shipments' (frm-ac823b8717fb428fa48b65b0efa4a2c3)
    
    	=== 'Images' section (fld-642fef453ecb4d32b74d2e34993da182) ===
    	'Image 02' photo (fld-28b749eeaff24492a730e427364ca683)
    	'Image 03' photo (fld-1f0ae66bce7e4b63981b244e40ce4366)
    	'Image 04' photo (fld-3cf1f20172104500af3070b96da2528e)
    	'Image 05' photo (fld-0a8930a83d1f41b68012178ffe54d2ab)
    
    	=== 'Linking Metadata' section (fld-fd8627a7114a431bb9199bdc2bd67ad8) ===
    	'Order Line Number' number (fld-da763fa0946d4be79039b4e828cf85f4)
    	'Purchase Key' calc (fld-8be9b2c2603f458f8349082237c41964)
    		Referenced Fields: 
    		 - Marketplace (fld-c163aba17ae64c4d93b5a53819a139dc)
    		 - Store Name (fld-3d98dc6cdcae4a88909c97c80dde7bfb)
    		 - Order ID (fld-e3e66a0f2e5c4df7b9496f65355e0bcf)
    	'Shipment Key' calc (fld-7652273e8d02496f8f8ebc6c46d93230)
    		Referenced Fields: 
    		 - Shipping Carrier (fld-12644a7a4ae24ed8a7926123832d3557)
    		 - Shipping Tracking Number (fld-6ea45a9c141343628940bfbcfa38ee90)
    	'Modified Age' calc (fld-9e5bc8ce982c4a468c4b66cad92ecc5b)
    		Referenced Fields: 
    		 - Date Modified (fld-59a06347614e48e8bf547a855b781582)
    	'Purchase Age' calc (fld-9675f0fb104847f0a9705da74bb8bd1a)
    		Referenced Fields: 
    		 - Purchase Date (fld-ccbd9a8f51d34246bebfb31aa4e397dd)
    	'UUID' calc (fld-13790925689a4a189aee77b2c4d0fcb6)
    	'Sample Calc' calc (fld-cf5f7b65e683481696a7e864ab39b3e5)
    		Referenced Fields: 
    		 - Title (fld-0d0edd2552ea461e929f806a4e5552b5)
    		 - Order Items::Title (frm-7a809372942a4031ae4bdf014f69e99b::fld-39ca9564ef2347ac93f933bc9a2316ac via fld-4862767002cf4aadad853e78dffb2eed)
    		 - Variant Data::Key (frm-efc0199a2b1543f79e722383014533b0::fld-ecc1b1ede8414912a63ec144012fa9e9 via fld-eb212e705eb34e9ea5cc4386ea7a9b1f)
    		 - Purchases::Purchase Key (frm-efc0199a2b1543f79e722383014533b0::fld-8be9b2c2603f458f8349082237c41964 via fld-2dfc5804be564f17bcc3c66fd1080121)
    	'Orders' from_form (fld-7bdce35a95dc42d596861eedf729eb73) join 'Orders' (frm-6c5adbc73d9f498c978b637c60d19561)
    			 ON Purchases.Purchase Key == Orders.Purchase Key
    	'Sync Toggle' check_mark (fld-b784d5a9b3bf435b93b71a20baa4d983)
    
    Orders: (frm-6c5adbc73d9f498c978b637c60d19561)
    	'Purchase Date' date (fld-bc2e4b152dee42ac9361539a6e37cb5d)
    	'Marketplace' text (fld-fa37906add2942c88bce3b500561c42d)
    	'Order ID' text (fld-8228040b4641449b96aabfaea15f1ac5)
    	'Store Name' text (fld-c153da2f9a504be4b6fee4b5b62a1c11)
    	'Store Name (Alt)' text (fld-9d12d614867b49d78ad1b9a5958d9bcd)
    	'URL' web_site (fld-fc8fb7f30fe4459495600e4d396160c2)
    	'URL Parser' script (fld-868cd41df6754bed94f90174262373a0)
    	'Shipping Cost' number (fld-288cfa093d164eb79f0432c722c71ba4)
    	'Sales Tax' number (fld-42664ebbbe98429c902b8669551d0d6e)
    	'Order Cost' number (fld-acdbf6132877436d8f86d12a7a732a13)
    	'Order Cost (Items)' script (fld-34223ce7a81d49af8fcf34b498348760)
    	'Vouchers' number (fld-3242366818524c3cb6ac65851a49a599)
    	'Total Cost' calc (fld-a4f4eff5a667421fa84fb319bb3f9f30)
    		Referenced Fields: 
    		 - Order Cost (fld-acdbf6132877436d8f86d12a7a732a13)
    		 - Shipping Cost (fld-288cfa093d164eb79f0432c722c71ba4)
    		 - Sales Tax (fld-42664ebbbe98429c902b8669551d0d6e)
    		 - Vouchers (fld-3242366818524c3cb6ac65851a49a599)
    	'Currency' text (fld-a069572060fe46daa4f151f7b4ff84cc)
    	'USD Total' number (fld-568f8cf940824f70bd12d2d5bf8091f2)
    	'Payment Method' text (fld-84341c7fc70f43f29bdc277a879a3d6f)
    	'Statement Entry' text (fld-f18af4bc1ed047f2a4820c6bfe507688)
    	'Note' note (fld-eb7bbf4f816844739549ae82b19ea8eb)
    	'Shipping Address' note (fld-d85b9118ea0346bea2b29c337c68bc60)
    	'Ship Date' date (fld-6ab700ccc11d418fbd27d8899d00c7a9)
    	'Delivery Date' date (fld-4b1c4180dc1b4bb08b32d16fa60cae66)
    	'Order Item' form (fld-9db0c7698499435ab6b18b7eb420e0ae) toMany 'Order Items' (frm-7a809372942a4031ae4bdf014f69e99b)
    	'Shipments' form (fld-db2fcdb4d79c466ea09671c47d2ae645) manyToMany 'Shipments' (frm-ac823b8717fb428fa48b65b0efa4a2c3)
    	'Purchases' form (fld-07c0ec05287a48c9a67b64d816007518) join 'Purchases' (frm-efc0199a2b1543f79e722383014533b0)
    			 ON Orders.Purchase Key == Purchases.Purchase Key
    
    	=== 'Calcs' section (fld-41cdc6a954524c05b9ec9e04c878f150) ===
    	'Alternate Order ID' text (fld-e0cc0e4c813848d6bb1dbe7fb5574c4a)
    	'Alternate Order ID Autocomplete Script' script (fld-75daa7631d7d4a10821b7cdd1df43104)
    	'USD Autopopulate Script' script (fld-89d9508a06594cf7bc5f4409699b796d)
    	'Shipping/Delivery Autopropagate Script' script (fld-544b7acca8b64e98b78bef29cdc6ac2c)
    	'Purchase Key' calc (fld-3e49aaa5bc32429c8f0f0f234878356d)
    		Referenced Fields: 
    		 - Marketplace (fld-fa37906add2942c88bce3b500561c42d)
    		 - Store Name (fld-c153da2f9a504be4b6fee4b5b62a1c11)
    		 - Order ID (fld-8228040b4641449b96aabfaea15f1ac5)
    	'USD Total Calc' number (fld-a50be30e2a974dee84a68195ffac913f)
    	'Aggregate Shipping Tracking Numbers' script (fld-7e8c8aa428304e53b9a559b6e6651d94)
    	'AutoURL' script (fld-b658ac413ef04b298d57121cc1206f82)
    
    Order Items: (frm-7a809372942a4031ae4bdf014f69e99b)
    	'Title' text (fld-39ca9564ef2347ac93f933bc9a2316ac)
    	'Title (Native)' text (fld-ef385456de924ee2ade8db3fec9415c7)
    	'Transaction ID' text (fld-9330e89b024e40cc86f541dc4c3fe686)
    	'Price' number (fld-a2973999a60d4319baf0b4480d6f57a0)
    	'Quantity' number (fld-39379cdff743496f9a1ccbdc1ae56297)
    	'Line Number' number (fld-f95b68d488cb4b058bbf3de84e1a7c3b)
    	'Total Price' script (fld-a2339a503f3d458ebfc0f9e7aa831017)
    	'Note' note (fld-d0cfab9ec09d497294fbd8b5b52caf16)
    	'Note Parser' script (fld-f1a20232b9ab4286b790fa57c4c4b0cc)
    	'Details' form (fld-ac04de32d98242b88333977c89526fc1) manyToMany 'Purchases' (frm-efc0199a2b1543f79e722383014533b0)
    	'Order' from_form (fld-c3a6725d7d9446da92bbb880ffe90a9e) toOne 'Orders' (frm-6c5adbc73d9f498c978b637c60d19561)
    	'Shipments' from_form (fld-0489f6c24c50466f9348313584893941) toOne 'Shipments' (frm-ac823b8717fb428fa48b65b0efa4a2c3)
    	'Gallery' from_form (fld-6ffd4369da0b418fb790a975f69a0ab2) manyToMany 'Gallery Items' (frm-1dd95cbe70cc490c972487920317620c)
    	'Default Values' script (fld-7c7222480794423a844685e6bd5954ab)
    	'Date Created' date_created (fld-6dcd45dd73a4463ca21378bf4ea48c69)
    	'Date Modified' date_modified (fld-b97807466ad044d0a646e06017db8ea1)
    
    Script Manager: (frm-a311565fe3614c5ca97a3942a2973450)
    	'Installed Version' calc (fld-c45a76a8b28b4546821f0a76d6076621) - calculation field missing formula!
    	'Source' calc (fld-6ecd7dbcad784799b651945616fc4e26) - calculation field missing formula!
    	'Enable Updates?' check_mark (fld-077d7d4c5619419abb25c7e513e61697)
    
    Shipments: (frm-ac823b8717fb428fa48b65b0efa4a2c3)
    	'Tracking Number' text (fld-c487390743c947969cbe661cff596855)
    	'Carrier' text (fld-0950c430cb0c41f79c51d43a544b366b)
    	'Tracking Details' script (fld-7a29242731d9451092c92d8586dbc94a)
    	'Alternate Tracking Numbers' table (fld-cf8718051bea4cc2aba0069ae76f32b7)
    		- 'Carrier' text (fld-193ef28f49c04c73affcfbba09001524)
    		- 'Tracking Number' text (fld-7342203d8f36415191bf8419fb6f70dc)
    		- 'Notes' text (fld-82a805c52d3c4408a775a3fc04bdc19f)
    		- 'Tracking URL' web_site (fld-de244f5ddb5d4f4ba86f218d7c0bf141)
    	'Tracking URL' web_site (fld-83e7a9bd104e495fb48de1da74b00c43)
    	'Tracking URL Autocomplete' script (fld-dddcdc15e1c44aa4a99bba6314dc7a07)
    	'Shipping Date' date (fld-1aa32f17e059424fb4e24bf894b34fdf)
    	'Received Date' date (fld-e3e3539ee04f4cc7971c7098c572104d)
    	'Unverified' check_mark (fld-abdb319b7db74fc39812a94778c433cc)
    	'Note' note (fld-b6352a3e22ca4a7d966cf4a216a7c135)
    	'ZIP Code' number (fld-4f73faa8937446a0a3b24e6dd4624d6b)
    
    	=== 'Join Fields' section (fld-42dce0fcedce4368b334ab72b765e7e3) ===
    	'Date Propagation' script (fld-f7aba3b5ddd6430cb8e9a211e0086c84)
    	'Order Item' form (fld-f3c8f85d6dd14c2f8199d050ad7fc5f9) toMany 'Order Items' (frm-7a809372942a4031ae4bdf014f69e99b)
    	'Purchases Join' form (fld-5c4a2d1aadad4005a82d424216d1bb7b) join 'Purchases' (frm-efc0199a2b1543f79e722383014533b0)
    			 ON Shipments.Shipment Key == Purchases.Shipment Key
    	'Shipping Events' table (fld-1ed7b8bddb8a463fa10b94ac11d64ecd)
    		- 'Date / Time' date_time (fld-6d279f9411c8497d9f6dcd2d74c01ef6)
    		- 'Location' text (fld-93730ed5a3ab41749b972d17c8c6880f)
    		- 'Message' text (fld-c861230085ab4b46ac05feab59a5add0)
    	'Shipment Key' calc (fld-201444109af7460d831ce21a96087e13)
    		Referenced Fields: 
    		 - Carrier (fld-0950c430cb0c41f79c51d43a544b366b)
    		 - Tracking Number (fld-c487390743c947969cbe661cff596855)
    	'Date Created' date_created (fld-8b02c9de87d240dba0aa9b774a5deca1)
    	'Purchases' from_form (fld-691985f25f2c4ce8b36dcc112a3ae600) manyToMany 'Purchases' (frm-efc0199a2b1543f79e722383014533b0)
    	'Orders' from_form (fld-6ee418159c264ff5bb1b5da1fde43e2f) manyToMany 'Orders' (frm-6c5adbc73d9f498c978b637c60d19561)
    
    Gallery Items: (frm-1dd95cbe70cc490c972487920317620c)
    	'Image' photo (fld-66620a6542a14b4eb3df98aa19f0afac)
    	'Title' text (fld-c4919a9d54c142b78eaf0fef3cc91e73)
    	'Keywords' text (fld-de6f53f4658f4321a77377f6bb9a736c)
    	'Source' web_site (fld-c32969738e4c4ab7947c53054c82bef8)
    	'Source Scraper Script' script (fld-0a45936b78e847fe8aeb2da089ac3fae)
    	'Purchases' form (fld-c5ae0e2263334e07ab558734ba6f4f9c) manyToMany 'Purchases' (frm-efc0199a2b1543f79e722383014533b0)
    	'Order Items' form (fld-c352a2dfa2884fb7ab9f380a08860ba3) manyToMany 'Order Items' (frm-7a809372942a4031ae4bdf014f69e99b)
    	'Date Created' date_created (fld-721df5a648de40a194a40bb8ab7d1946)
    	'Date Modified' date_modified (fld-4655757bd1824f70ad42fc558776f65b)
    	'Notes' note (fld-f6ce1405bd7a435080c03f8b0598c9f5)
    	'File Attachment' file (fld-b2f3efd087fb4d5f853309ef79ab3d31)
    	'Metadata' table (fld-7ccfc47e23194d6b8856632dabb3097d)
    		- 'Value' text (fld-4bf84f891e544ba6a03c56d1978ef4b2)
    		- 'Date Created' date_created (fld-8369762f3c7b410ab7f5c92dd87f132c)
    		- 'Key' text (fld-d5e45b1c9a184aaeb26622a7eae3ca8f)
    	'Extended Metadata' text (fld-b8e7d09b55384e45a9922bf652e05f96)
    
    Desirable Acquisitions: (frm-20f8844810bb4884a22ab1a3c0e143a4)
    	'Name' text (fld-bdd887ce763243bc847afdf6f2549f52)
    	'Notes' note (fld-c3920264a1b54927831a8984de7ea984)
    	'State' text (fld-9cebaa1a64254c4ba4bd064eeeb72a81)
    	'Date Created' date_created (fld-361ec793242e40b38657d9563681dab9)
    	'Date Modified' date_modified (fld-6845c7dbbeaf4ac9915cee48b00c5f72)
    	'Photo' photo (fld-b9ad86e8707c460885002b828b8dadc1)
    	'Web Site' web_site (fld-e0b4c7a6bb82474297b38e2ccc1fe39a)
    	'Acquisition Samples' form (fld-2eb1061b9fce4dd5a5508896c22c3784) toMany 'Acquisition Samples' (frm-34193fbd729f498194bff2d11bec5de0)
    	'Purchases' form (fld-3314dab138a14046862da7dc3700e11c) manyToMany 'Purchases' (frm-efc0199a2b1543f79e722383014533b0)
    	'File Attachment' file (fld-0287b866efa0428d9dc417d7531b39c3)
    
    Acquisition Samples: (frm-34193fbd729f498194bff2d11bec5de0)
    	'Title' text (fld-e2f18890c0344e82a6486704ea65f527)
    	'Notes' note (fld-ad2c2752eefb4d4eb96220ff1b042ad9)
    	'Source' web_site (fld-25b14dc7565d40a1b58121554ba8a4aa)
    	'Price' number (fld-72464af6aea84a3d8e26a8c17f39738f)
    	'Pictures' photo (fld-265e6017684547fb8cb0a891a89e35c8)
    	'Desirable Acquisitions' from_form (fld-6b1b4faa00094613a1ce44c582393d36) toOne 'Desirable Acquisitions' (frm-20f8844810bb4884a22ab1a3c0e143a4)
    	'File Attachment' file (fld-c59caf13ff1941acbc700b281feb7a72)
    
    #36117
    D J Leason
    Participant

    @Sam Moffatt
    Is privacy and security the main reason for choosing CouchDB over iCloud?
    Do you recommend downloading the iOS version in the beginning or after you have all your forms build? What determines that decision?

    Are there a lot of differences in syntax between the Mac and iOS versions and do they work seamlessly with each other despite those differences?

    Let’s talk form building and linking strategy for a minute. If you have a main topic, we’ll use medicinal herbs for example, :)

    I want to track: Broad categories and intricate details about each herb.

    1. History of each:
    Acquired it: When, where who from, how and why acquired: Grew it, Bought it, Wildcrafted it.
    Positive identification attributes of each herb.
    2. Culinary Information
    a. Edible parts
    b. Various possible preparations
    c. Nutritional information
    d. Recipes

    3. Growing Information for each herb, both recommended and actual and success rate of each method.

    4. Medicinal Information: Properties, Actions, Constituents, Various medicinal preparation possibilities .

    5. Work in Progress- Start, Strain, Bottle, Label, and Store

    6. Expenses: Assets, Supplies (consumable, Functional, Packaging)

    7. Inventory:
    Location,
    Container size and date,
    Amount on hand,
    Age and expiration date
    Consumable Supplies
    Macerating
    Ability to increase and decrease amount in each, broken down by preparation type:
    Tinctures,
    Infused Oils,
    Vinegars,
    Macerating
    Consumable Supplies,

    My spreadsheets have become too long, too many, too time consuming and too redundant and added to that using Quicken to manage the expenses. So the broad end goal here is to greatly reduce the paperwork time and organization of it all by entering each piece of information about each herb ONCE and being able to, at a click, see any individual piece of information or all the information about a particular herb.

    As far as data entry for new records goes, the more input boxes where necessary, multiple choice check boxes and radio buttons where possible and branching decisions via IF, Then, Else statements seems logical to me but I have no experience with databases so I am open to suggestions.

    That being said, design-wise, Is it better to have more or fewer forms?

    For the forms that I do create, (all information revolving around each individual herb), should they all have a one to many link with inverse relationship checked? Or say, in the case of storage location and growing conditions, since they all have them, be linked as many to many? I am unclear as to what determinations to consider in the design phase. Is that determined by how you want to view the end results?

    Ideally, I imagine an opening screen asking me which herb I want to work with and letting me choose either from a list of Common name OR Latin name.

    Once chosen, it would ask me what a I want to do with the herb and show me the following choices:

    Acquire it,
    Grow it
    Process it – Dry it , Freeze it, Package it or Store it
    Work in Progress
    Start a Preparation –
    Strain a Preparation
    Build a value added product
    Research it
    Count it
    Find it – Finished product in storage or Macerating
    View Logs
    Daily Log
    Individual herb log
    Herb Identity Checklist

    Once chosen then launch into each aspect of those categories and store any input information in a record under that herb.

    Then there is the question of importing the past 8 years of data. Should I arrange the spreadsheet columns to match the new data records tables or design the new data entry to match the spreadsheet columns?

    Thoughts?

    #35955
    Sam Moffatt
    Participant

    You just need a P2P network between the MBP, the iPad and the iPhone out in the field which you could possibly set up ad hoc from the MBP however the iPhone would lose internet connectivity when you joined that network. You might be able to set up the phone to be the hotspot to create a network and that might depend upon your carrier though I’m not sure how many devices it’ll let you connect.

    In P2P mode all three devices would need to have each other added so their changes replicate to each other. If your MBP is always going to be on, you can also set it up so that the iPhone and iPad just add the TF instance on the MBP and then the MBP adds the other two devices (sort of like a star network). You could also install CouchDB on the MBP however since it won’t have a fixed identity, I’m not sure I’d recommend that.

    Then for your home network, I’d again keep it simple and have the MBP and the iMac configured via P2P to talk to each other and then you make sure TF is open on both devices and everything syncs. If you’re missing something from the iPad or iPhone then you’d have to make sure they’re open. You could run CouchDB on your iMac or you can keep TF open on it as well. You could also configure the iMac to try to pull via P2P from the mobile devices as well.

    I used to have a similar set up with multiple iPhones and iPads all hooked up to each other via P2P and I ended up moving to hub and spoke first (I had an iMac at home running TF as a hub which had all of the devices added to it and then they all only added the iMac) to now using CouchDB on the iMac with everyone pushing to that. If you’re willing to pay for it, setting up an external CouchDB that all devices use would be the ideal way but for your use case, I think having P2P set up might be enough.

    One word of warning though, Tap Forms uses a “last write wins” sync system. This means that if you change the same record on two devices (e.g. a conflict), then when it comes to resolving those conflicts the latest change is used. If everything is connected all of the time (external CouchDB or everything is up to date via P2P) then this is less likely to be a problem but it is a behaviour you should be careful with. That said you can easily add the “Date Modified” field to your form which will automatically update each time the record changes so you can quickly see when the last time the instance of TF that you’re using thinks the record changed. If this is a date earlier than your latest changes, then you’ll know that something is out of date and to get the sync working again. If you can afford it, a cloud hosted solution that all devices can talk to as you make changes would be the way forward.

    My sync setup: 2 iPhones, 3 iPads, 1 MBP, 1 iMac (TF+CouchDB); I also have a cheap Dell machine running Ubuntu Linux with CouchDB on it as well as an extra backup.

    Edit: One extra thought, if your iMac at home was always on and you’re comfortable configuring your network, there are guides on the forum on how to expose that CouchDB instance externally with SSL and dynamic DNS. You can then self host the CouchDB but at that point for it to work you’d need some sort of MiFi for the MBP and any other device that doesn’t natively have a cellular connection. I’m also not sure how much data that’d cost on either end to replicate based on your use cases.

    #35108

    In reply to: iCloud sync issues

    Sam Moffatt
    Participant

    Could you use the CouchDB based sync instead? I’ve shifted everything over as soon as it was available but this requires setting up a CouchDB server. I have an iMac at home that is always on and I run as my CouchDB server but this does mean that when I’m not at home my changes don’t get automatically sync’d from my devices like they would with iCloud.

    One other thing I’ve been wondering about for a while now is if there is much interest for having a TapForms specific hosted CouchDB set up. Pay as you go, probably one dollar per gigabyte stored per month (most used storage for the month; probably a minimum of $5/month to deal with CC fees and the like), set up with a standard SSL certificate and georeplicated backups. For the most part I rely on my own internal network and VPN into it but I’ve been wondering about setting this up more formally and then seeing if there is external interest.

    A feature that I’d like to see if I can get interest in is being able to provide more uniform support for backups. I have my own scripts that I run internally that do two different sorts of backups (one is like Time Machine and another tries to get every single change). Backups would be charged on a similar cost per gigabyte used model though I wouldn’t want to launch that until there was a user interface for it that doesn’t exist right now. I’ve already used my backup system to restore a field script that was thoughtlessly nuked so I know it works but I’d be looking to build a UI around this. These backups are brick level backups that backup individual records which means you can restore a single entity in Tap Forms (such as a record, a field, a script or even a form) without having to bring the entire Tap Forms document along.

    Is there any interest in that?

    #34952
    Sam Moffatt
    Participant

    A few thoughts, not sure if these will help solve your problems. I’d start normalising your data a little because that will help you aggregate on those axis (e.g. https://en.wikipedia.org/wiki/Database_normalization).

    The first step I’d take is to create a form with hosting provider in it. Each hosting provider is a record in this new form. Then you can use a Link To Form field as either a 1:M or JOIN type to go from the hosting provider to the customer (1:M assuming each website/customer is only hosted at one place, you could do M:M if that isn’t true; if you have a “key” column for the hosting provider in place you can use this for the “JOIN” field, a text field with a controlled value is enough).

    Doing this will force you to create a record per hosting provider however the Link To Form inside of it will give you quick aggregations on the numeric fields. See a screenshot of roughly what I mean. This might not be everything you need but you can use scripting to create a text entry with the data you want for that hosting provider. At the very least this makes filtering by hosting provider relatively trivial and building JavaScript aggregations a little easier. It is a little more work to get set up but you should be able to experiment on a backup to see what I mean.

    If you go for the JOIN option, you should be able to do this by creating the hosting entries you need. You could automate that but that might be more hassle than it’s worth unless you have a lot of hosting providers. If you go for the 1:M or M:M options, then you need to link all of the records together by hand or again write a script to do it for you. Either of those choices will make sense depending on the volume of data you have and your own inclinations. As always before doing any of these tasks: make a backup first, restore it to a new document and disable any sync you have enabled to prevent changes from propagating. That way if you make a mistake, you can be confident you didn’t toast your only copy.

    Attachments:
    You must be logged in to view attached files.
    #34422

    In reply to: Sync via Synology NAS

    daffy
    Participant

    Hi, this is in reply to the detailed help provided by @elliottcable above.

    I am wanting to use CouchDB on my synology drive because I’m having trouble with the iCloud sync.

    My concern is that I am not quite techie enough to do it. I did manage to set up the NAS drive, but it took a lot of reading and testing (and patience!).

    How user friendly is the system you have described? Would I need specialist knowledge to enable me to set it up?

    I have a domain name I can use and I understand SSl enough to be able to set it up (I think), but I’m unsure about the DDNS instructions you linked to.
    https://www.synology.com/en-us/knowledgebase/DSM/help/DSM/AdminCenter/connection_ddns
    I thought it would be something I needed to install on my NAS, but perhaps I misunderstood. I find the Synology ‘help’ files often miss out crucial info that would enable someone with slightly less tech knowledge to be able to implement their instructions.

    I’d very much appreciate your thoughts on how achievable this might be for me. If it’s way above my knowledge and I can’t learn enough by reading up, then perhaps it’s too much for me to embark on.

    Cheers,
    Nicky

    #34078

    In reply to: Sync via Synology NAS

    ELLIOTTCABLE
    Participant

    Since I came across this early-on when preparing to set all this up, and it looks like a few people have had trouble with this, I thought I’d apply some of my knowledge and leave a resource for future Googlers.

    First off, some links from which I pieced all of this together:

    ~~ Prerequisites ~~

    First off, I’m assuming you already have Synology’s dynamic DNS aka ‘DDNS’ (tutorial), a custom domain-name (tutorial), and a Let’s Encrypt SSL certificate (tutorial) setup. If you haven’t done those, do them! They’ll make your life easier not just for Tap Forms, but for … basically everything. Very worth your time (and a couple bucks if you don’t already have a domain.)

    ~~ Installing Docker and CouchDB ~~

    First off, visit the ‘Package Center’ to install Docker and Synology’s Docker ‘app’:

    Once it’s installed, open it from the Main Menu, in the top left. The overview you’ll be presented with is pretty useless, as you haven’t downloaded any “images” (templates from which you can create apps, basically), nor started any “containers” (said apps) yet.

    There’s two images we’re going to want to install and configure: the CouchDB server itself, and the official GUI CouchDB management tool known as ‘Fauxton.’ Go ahead and select the ‘Registry’ tab on the left in the Docker app:

    You’re going to download those two images here. For each of these, use the search field to find the image, right-click it, and then click “Download this image.” When asked to choose a version, accept the default of “latest.”

    Repeat this for both these image names:

    • couchdb
    • 3apaxicom/fauxton

    When they’re both downloaded, click ‘Images’ in the sidebar, and verify that both of the above are listed.

    ~~ Starting CouchDB ~~

    Next, we’re going to create an actual container out of the CouchDB image — an instance of the app, configured and running on your Synology.

    In that ‘Images’ section of the Docker app, select the CouchDB image, and then click ‘Launch’ to bring up Synology’s container-wizard:

    Give the container a unique name, and feel free to limit the available resources; then click ‘Advanced Settings:’

    Configure the following:

    1. Enable ‘auto-restart,’ to ensure Tap Forms can always sync.
    2. Create a folder on your NAS for the CouchDB server’s data and configuration. I used <volume>/docker/tapforms/ as the root, for instance; and you’ll need several subdirectories, as described below.

      Within that root, you’re then going to add add Docker volume mappings to each of the CouchDB directories:

      • <volume>/docker/tapforms/etc, mounted to the image’s /opt/couchdb/etc/local.d
      • <volume>/docker/tapforms/data, mounted to the image’s /opt/couchdb/data
      • <volume>/docker/tapforms/logs (plural), mounted to the image’s /opt/couchdb/log (singular)

      For each of the above (under the ‘Volumes’ tab of ‘advanced settings’ while creating the container) you’ll have to click ‘Add Folder’, and select the first path — on your NAS volume — from a tree:

      Then, you’ll have to click the ‘Mount path’ field, and type the second path — the one inside the container — into the field:

    3. Map the Docker container’s CouchDB port to the NAS’s local, internal CouchDB port.

      Switch to the ‘Port Settings’ tab. Click ‘Auto’ next to the entry for 5984, and change that to also be 5984:

    Finally, click ‘Apply’ to close the advanced settings, and then click ‘Next.’ You should see a summary of the settings (the super-important volume-mount paths won’t be listed, so watch out.) Click ‘Apply’ again:

    Synology will now boot the container in the background; so let’s go setup the other one while we wait.

    ~~ Starting Fauxton ~~

    Repeat the above, but for the 3apaxicom/fauxton container. Give it a unique name, and limit the resources appropriately. Tell it to create a DSM desktop shortcut, at the port 8006 — that’s not a typo, we’ll get it all hooked up together later:

    Change the Synology-local port from ‘Auto’ to 8005; (again, not a typo):

    Now, for a weird bit: you need to create a ‘link’ between the containers. This is a secure, secret port, basically. Click the ‘Links’ tab of the advanced settings, and click the ‘+’ to add one. Select your CouchDB container; and then type db as the alias:

    Finally, change the ‘Execution Command’ under ‘Environment’ to exactly this command, quote-marks and everything: sh -c 'fauxton -c http://$DB_PORT_5984_TCP_ADDR:$DB_PORT_5984_TCP_PORT'

    Apply, Next, double-check, Apply. Boom! Both containers should be running. Click over to the ‘Containers’ tab in the Docker-app’s sidebar to double-check:

    ~~ Configuring port-forwarding, SSL, and reverse-proxying ~~

    Phew! We’re halfway there. Let’s take a break from Docker, and double-check some Synology DSM settings that are really important. First, Synology’s built-in reverse proxy — this will ‘hide’ all our shmancy CouchDB passwords and stuff behind secure HTTPS / TLS encryption.

    Twice, we’re gonna: open ‘Control Panel,’ ‘Application Portal’ (yeah, I don’t get the name either), ‘Reverse Proxy.’ Click ‘Create.’

    You’re gonna route incoming requests from (confusingly called ‘Source’) HTTPS, on your domain-name, port 6984, to (called ‘Destination’) HTTP on localhost, port 5984:

    Hit ‘OK,’ then repeat for the web-GUI we installed — this time, route incoming requests from HTTPS, on your domain-name, port 8006, to HTTP on localhost, port 8005. You can also enable HSTS and HTTP/2 on this one.

    Then, you’ll need to configure your router’s port-forwarding. Luckily, Synology is absurdly badass, and can do most of that for most of us — as long as your router has something called UPNP. Synology has rather thorough documentation on this, but at least for me, it was about this simple: open ‘Control Panel,’ ‘External Access,’ ‘Router Configuration.’ Click the ‘Set up router’ button at the top.

    Then, ‘Create’ some rules, and select ‘Built-in application.’ Do not select the Docker entries — select, instead, the Reverse Proxy entries you just created for ports 8006 and 6984; then hit ‘Apply.’

    (You may have to do this manually, on your router, instead. I’m afraid I can’t help you there!)

    ~~ Configuring CouchDB ~~

    Let’s verify that everything’s routed properly. Open https://yourdomain.blah:8006 in a new tab (you should be able to just click the icon on the DSM homescreen, too, if you set that up above.)

    If Fauxton loads, then head on over to the ‘Verify’ tab on the left, and click ‘Verify installation.’ Everything should succeed (except maybe the replication section? Not sure what’s up with that, but it consistently fails for me.)

    Next, we need to lock down the installation. Right now, your CouchDB is running in “Admin Party” mode — which is a cute way of saying ‘horribly insecure.’ Literally everybody on the Internet currently has admin access to your database, oh no!

    Let’s fix that. Click ‘Setup’ in the sidebar, then ‘Configure a Single Node.’

    You’ll be presented with a form via which you can add what is effectively a root password to your CouchDB server. (Note that this is *not* your personal non-admin user-account! We’ll create that later.) Choose a secure root password, write it down somewhere (may I heartily suggest 1Password? ?), and create your administration account. Finally, enter :: (exactly two colons, no spacing) as the ‘bind address’, and leave the port alone.

    Once you’ve submitted that, reload the page — Fauxton won’t be able to successfully make any more changes to your CouchDB installation until you’re logged-in under that root account. Enter the information you just saved, and hit ‘Log In.’

    Switch over to the ‘Config’ sidebar entry, and let’s tweak some configuration values:

    1. Set [chttpd] require_valid_user to true
    2. Set [log] file to /opt/couchdb/log/couch.log
    3. Set [log] writer to file

    Now — before you close the page! — you need to make sure Fauxton can still authenticate with CouchDB. This isn’t very clear, and took me ages of searching, but it turns out you need to *add* a config-option. Click ‘Add Option’ at the top of the page, and enter the following three values, precisely: httpd, WWW-Authenticate, and Basic realm="administrator" — spaces, quotes, and all. Then click ‘Create.’

    The very last step of configuration there, is to create a non-admin user for Tap Forms to authenticate as. (This is optional, but a good idea in general.)

    Click over to the ‘Databases’ tab in the sidebar, and select the _users database. Hit ‘Create Document.’

    Delete everything in the text-editor that appears, and replace it with the snippet from this Stack Overflow answer, changing your desired user-name (in two places!) and password as appropriate:

    Click ‘Create Document.’ (Note that CouchDB will hash up that password you enter and store it safely; you’ll never be able to view it again. Store it in 1Password, too!)

    Now that you’ve done all that, reboot the CouchDB container so that the new configuration will take effect. Return to DSM, open the Docker app’s ‘Containers’ tab, right-click on your CouchDB container, and select the ‘Restart’ action:

    If you’re Terminal-savvy, you can give your server a real quick test: run curl https://ds.ell.io:6984/, replacing the domain with the one you’ve set up for your DiskStation or your Synology.me DDNS domain. If you’ve got everything working, you will get an error — that’s what we want! Something along the lines of {"error":"unauthorized","reason":"Authentication required."}.

    ~~ Configuring Tap Forms ~~

    You’re in the home stretch! I know it’s been a slog, but we’re, finally, almost done.

    The very last step is to configure Tap Forms itself on your devices. Brendan covers it pretty well, so I’ll just add some addenda and errata to his writeup here:

    • Ignore ‘Installing CouchDB’ and ‘Setup,’ we just did all that …
    • … except for the notes on admin accounts. Basically, you should sign into the root account we created earlier inside a Tap Forms app at least once, so it can create your db-deadb33f... databases. Then you can tap sign out, and sign back in using the second, non-administrator account you created.
    • Pretty much everything about SSL can be ignored: Synology’s reverse-proxy handled this for us.
    • It was unclear to me, and maybe also to you … so note that all of the above is specific to a single ‘database’ in Tap Forms. There’s no way to configure Tap Forms as a whole to sync all of its databases via CouchDB, and you’ll have to duplicate the setup for every new database you create.

    Hope this was helpful to someone! Maybe I shouldn’t have spent like six hours writing it up, yikes. I’ll be ‘following’ this thread via WordPress’s settings, so I’ll get an e-mail if you have any questions — though I’m not sure how much help I can offer, as I’m definitely not an expert on any of the above!

    #33671

    In reply to: iCloud sync issue

    Brendan
    Keymaster

    Apache CouchDB is quite reliable. It’s the native sync service that’s built-in to the Couchbase Lite database engine that Tap Forms uses.

    To get it setup with Amazon, I recommend going through bitnami.com

    https://bitnami.com/stack/couchdb/cloud

    It basically sets up CouchDB for you.

    Although once you get that setup then you have to either setup an SSH tunnel to get access to the database stored in AWS, or open up the “Elastic” IP addresses they give you to the public to be able to connect to them directly. But if you do that, then you’ll want to use SSL, so you’ll need a certificate. It can get complicated.

    I’ve done it with tunnelling in and then using http://localhost:5984 to connect on the Apache CouchDB area in Sync Settings in Tap Forms.

    #33536

    In reply to: Date Fields

    Mark Kristan
    Participant

    Thank for that reply, Brendan, but you misunderstand my questions, maybe I should ask them in separate posts. As for doing what you say about the proper conversion from B4 to TF, I am aware that there is supposed to be a way to do this but I decided it is not worth the hassle for these few db docs, I would have to try to find an older copy of my operating system (maybe use the install disc I have and end up with Mountain Lion, I think, then upgrade one by one to Mavericks, or whatever, on order to run Bento). I have the raw data for those databases, I will just use that without all the proper formatting, but my question really relates to even a brand new TF document I create.

    About the column to the L of the main body of the database in the default view (single column view), I attached a screenshot of that document with a freehand line drawn through the column I am talking about. This column contains dates, the information taken from the “Date Created” field in the document; this would be fine for a document where the date is an important field (such as a db doc I created for trips I do for work, if I wanted to know what I did on, say, some date in August of 2014, it would be easy to scroll down to those dates in that column); in this case, it would be a lot more useful if I could configure this document such that Tap Forms would take the data in a different field and put it in that column (I would choose the “Artist” field – would make it much easier to navigate to media I own by that artist); I can choose multi column view, make it bigger so that I don’t only see like five records, click on “Artist” and click on the arrow to sort ascending or descending, but it would be a lot quicker to just scroll down that column on the left to that artist (there is a letter at the top of each grouping of artists that start with that letter, but I still have to click on a date, then look at what comes up for a record on the righ, then if it isn’t what I’m looking for scroll to find the record I am looking for). Is there a way to program Tap Forms to put the data from another field in the document, other than “Date Created”, in that column to the left of the main body/record in the document? I do know how to change the order of records by dragging a field up or down in the form editing section.

    Thanks

    Attachments:
    You must be logged in to view attached files.
    #30757

    In reply to: Encryption and sync

    Brendan
    Keymaster

    Hi Drew,

    When Tap Forms establishes a connection with Apple’s CloudKit servers for syncing, that connection is encrypted. The data stored on Apple’s CloudKit servers is encrypted according to Apple’s iCloud security page here: https://support.apple.com/en-ca/HT202303

    CloudKit is the underlying infrastructure that’s used by iCloud Drive. So in the above page Apple doesn’t mention CloudKit, but they do mention iCloud Drive. So according to Apple, the data is encrypted in transit and while sitting on the server.

    When Tap Forms reads the data from disk, it’s reading an encrypted disk, but it decrypts the data as it loads it into memory. It’s this data that’s synced to iCloud.

    When you sync to another device, the data is read from Apple’s CloudKit servers using your own iCloud credentials. That data is then transmitted to Tap Forms on your other device over a secure, encrypted SSL connection.

    When the data is then stored in the Tap Forms database, whether it is encrypted or not depends on whether the document you are syncing has its encryption enabled or not. So in order to have everything fully encrypted, you’ll need to just make sure you’ve enabled encryption for that document on all your devices.

    Yes, that means that if someone were to get a hold of your iCloud username and password, they would be able to get access to the Tap Forms database documents in an unencrypted state. But that goes the same for your iCloud Drive files, your Mail account, your Calendar, Notes, and Reminders, etc. Basically anything in iCloud.

    The encryption that Tap Forms provides is “on-device encryption”, which is determined by you if you have the encryption enabled or not for the documents you’ve created.

    Hope that makes sense.

    Thanks,

    Brendan

    #30146
    aleferr
    Participant

    Hi Brendan,
    have been using Tap Forms 5 for a while now and I’m very happy with the results, both in importing previous DBs from FileMaker Pro and creating new ones from scratch. I maintain the DBs on the Mac and sync with iPad and iPhone (with nearby sync working flawlessly, for me).

    One feature I really miss is the use of custom layouts in iOS! So my question is: are you planning to port this feature in iOS (or at least allow to set the fields to display in the standard list view) anytime soon?

    Thanks and keep up the good work!
    Alex

Viewing 15 results - 46 through 60 (of 140 total)
 
Apple, the Apple logo, iPad, iPhone, and iPod touch are trademarks of Apple Inc., registered in the U.S. and other countries. App Store is a service mark of Apple Inc.