Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
424 changes: 424 additions & 0 deletions docs/website/assets/css/extended/cn1-signing.css

Large diffs are not rendered by default.

96 changes: 95 additions & 1 deletion docs/website/assets/js/cn1-crisp.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,96 @@
}
};

// --- Crisp trigger events -------------------------------------------------
// Pages and product surfaces explicitly call the matching function below. This
// shared script handles consent, timing, and deduplication; it never guesses user
// intent from the current URL.
const firedThisView = {};
const pendingEvents = {};

const fireCrispEvent = (name, data) => {
// Consent can change after a page schedules a dwell event. Check it at the
// moment the event fires, before touching either deduplication guard.
if (getConsent() !== "accepted" || !window.$crisp || firedThisView[name]) {
return false;
}
try {
const sessionKey = `cn1-crisp-ev-${name}`;
if (sessionStorage.getItem(sessionKey)) {
return false; // already fired earlier this session
}
} catch (e) {
// sessionStorage unavailable (private mode) — use the per-view guard only
}
try {
const event = data ? [name, data, "blue"] : [name];
window.$crisp.push(["set", "session:event", [[event]]]);
firedThisView[name] = true;
try {
sessionStorage.setItem(`cn1-crisp-ev-${name}`, "1");
} catch (e) {
// sessionStorage unavailable — the per-view guard still applies
}
return true;
} catch (e) {
return false;
}
};

const requestCrispEvent = (name, data) => {
const consent = getConsent();
if (consent === null) {
// The page requested the event before the visitor answered the consent
// banner. Remember the request, but don't mark it as fired.
pendingEvents[name] = data || null;
return false;
}
return consent === "accepted" && fireCrispEvent(name, data);
};

const flushPendingEvents = () => {
Object.keys(pendingEvents).forEach((name) => {
const data = pendingEvents[name];
delete pendingEvents[name];
fireCrispEvent(name, data);
});
};

const clearPendingEvents = () => {
Object.keys(pendingEvents).forEach((name) => delete pendingEvents[name]);
};

const scheduleCrispEvent = (name, delay, data) => {
window.setTimeout(() => requestCrispEvent(name, data), delay);
};

// Explicit hooks for the pages and product surfaces that own each event.
const crispEvents = window.cn1CrispEvents || {};
crispEvents.consoleDwell60 = (data) => scheduleCrispEvent(
"ConsoleDwell60", 60000, data || { page: "console" }
);
crispEvents.signingScreenView = (data) => requestCrispEvent(
"SigningScreenView", data || { page: "signing" }
);
// Keep the original console-facing name as an alias.
crispEvents.signingScreenOpen = (data) => requestCrispEvent(
"SigningScreenView", data || { page: "console" }
);
crispEvents.buildError = (data) => requestCrispEvent("BuildError", data);
crispEvents.gettingStartedDwell = (data) => scheduleCrispEvent(
"GettingStartedDwell", 20000, data
);
crispEvents.pricingEvaluator = (data) => {
const firePricing = () => requestCrispEvent("PricingEvaluator", data);
window.setTimeout(firePricing, 30000);
document.addEventListener("mouseout", (event) => {
if (!event.relatedTarget && event.clientY <= 0) {
firePricing();
}
});
};
window.cn1CrispEvents = crispEvents;

const loadCrisp = () => {
if (window.CRISP_WEBSITE_ID || document.getElementById("cn1-crisp-loader")) {
return;
Expand All @@ -58,7 +148,9 @@
};

const hideCrisp = () => {
window.$crisp = window.$crisp || [];
if (!window.$crisp) {
return;
}
try {
window.$crisp.push(["do", "chat:hide"]);
} catch (e) {
Expand Down Expand Up @@ -92,10 +184,12 @@
setConsent("accepted");
closeBanner();
loadCrisp();
flushPendingEvents();
};

const declineConsent = () => {
setConsent("declined");
clearPendingEvents();
closeBanner();
hideCrisp();
};
Expand Down
2 changes: 2 additions & 0 deletions docs/website/content/compare.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,5 @@ MAF historically combined enterprise complexity with hybrid-web tradeoffs and a
## Bottom Line

If you want a Java/Kotlin-based, high-portability cross-platform workflow with strong native output and reduced platform build friction, Codename One is built for exactly that.

{{< crisp-event function="pricingEvaluator" >}}
2 changes: 2 additions & 0 deletions docs/website/content/comparison-chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,5 @@ Support is provided for the process of administering and installing the corporat
The corporate solution requires that your company perform the setup and installation of at least 4 separate servers with a complex configuration process. This requires a trained system administrator to perform the setup based on instructions from Codename One.

If you think the corporate server is right for you please fill out the form here.

{{< crisp-event function="pricingEvaluator" >}}
2 changes: 2 additions & 0 deletions docs/website/content/developing-in-codename-one.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ hero_image: "/uploads/Group-2270.svg"

- **[Tutorial Tag In the Blog](/blog/)**
The Codename One blog publishes tutorials regularly and you can follow all of them in this tag.

{{< crisp-event function="gettingStartedDwell" >}}
72 changes: 3 additions & 69 deletions docs/website/content/signing.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,6 @@
---
title: "Signing"
date: 2015-03-03
title: "Code Signing"
slug: "signing"
layout: "signing"
description: "Create and manage current Apple, Android, macOS, and Windows signing assets with the standalone Codename One Certificate Wizard."
---

# Signing

Code signing and provisioning for the various platforms

1. Home
2. Developers
3. Signing

**Important:** this document is out of date! Please check out the developer guide section [**here**](https://www.codenameone.com/developer-guide)

While Codename One can simplify most of the grunt work in creating cross platform mobile applications, signing is not something that can be significantly simplified since it represents the developers individual identity in the markets. In this document we attempt to explain how to acquire certificates for the various markets and how to set them up to the build.

The good news is that this is usually a "one time deal" and once its done the work becomes easier (except for the case of iOS where a provisioning profile should be maintained).

## iOS (iPhone/iPad)

iOS signing has two distinct modes: App Store signing which is only valid for distribution via iTunes (you won't be able to run the application yourself) and development mode.

Signing for iOS can be accomplished using the [Codename One certificate wizard](/blog/ios-certificate-wizard.html), for the advanced cases where you already have a certificate or the wizard can't answer your requirements you can follow the guide below.

You have two major files to keep track of: Certificate - your signature Provisioning Profile - details about your application and who is allowed to run it

You need two of each file (4 total files) one pair is for development and the other pair is for that precious moment when you are ready to upload to the App Store.

**Warning: this process only works on a Mac, the Adobe process linked here for Windows will produce an invalid certificate that will not WORK!** Adobe wrote a pretty [decent signing tutorial](http://help.adobe.com/en_US/as3/iphone/WS789ea67d3e73a8b2-240138de1243a7725e7-8000.html) on this subject for Air which you can pretty much follow to get the files we need (p12 and mobileprovision). They also cover the [certificate to p12 conversion process](http://help.adobe.com/en_US/as3/iphone/WS144092a96ffef7cc-371badff126abc17b1f-7fff.html). Currently as far as we know, the best option for developers who don't have access to a Mac is to use a service like [http://www.macincloud.com/](http://www.macincloud.com/).

The first step you need to accomplish is signing up as a developer to [Apple's iOS development program](http://developer.apple.com/), even for testing on a device this is required!

The Apple website will guide you through the process of applying for a certificate at the end of this process you should have a distribution and development certificate pair. After that point you can go to the [iOS provisioning portal](https://developer.apple.com/ios/manage/overview/index.action) where there are plenty of videos and tutorials to guide you through the process. You need to create an application ID and register your development devices.

You then create a provisioning profile which comes in two flavors: distribution (for building the release version of your application) and development. The development provisioning profile needs to contain the devices on which you want to test.

You can then configure the 4 files in the IDE and start sending builds to the Codename One cloud.

If you have problems along the way or fail to install the resulting files check out the troubleshooting guide [here](/blog/ios-code-signing-fail-checklist.html).

## Android

Its really easy to sign Android applications if you have the JDK installed. Find the keytool executable (it should be under the JDK's bin directory) and execute the following command:

```
keytool -genkey -keystore Keystore.jks -storetype JKS -alias [alias_name] -keyalg RSA -keysize 2048 -validity 15000 -dname "CN=[full name], OU=[ou], O=[comp], L=[City], S=[State], C=[Country Code]" -storepass [password] -keypass [password]
```

The elements in the brackets should be filled up based on this:

- Alias: \[alias\_name\] (just use your name/company name without spaces)
- Full name: \[full name\]
- Organizational Unit: \[ou\]
- Company: \[comp\]
- City: \[City\]
- State: \[State\]
- CountryCode: \[Country Code\]
- Password: \[password\] (we expect both passwords to be identical)

Executing the command will produce a Keystore.ks file in that directory which you need to keep since if you lose it you will no longer be able to upgrade your applications! Fill in the appropriate details in the project properties or in the CodenameOne section in the Netbeans preferences dialog.

For more details see [http://developer.android.com/guide/publishing/app-signing.html](http://developer.android.com/guide/publishing/app-signing.html)

## BlackBerry

You can now get signing keys for free from Blackberry by going [here](https://www.blackberry.com/SignedKeys/). After obtaining the certificates and installing them on your machine (you will need the Blackberry development environment for this). You will have two files: sigtool.db and sigtool.csk on your machine (within the JDE directory hierarchy). We need them and their associated password to perform the signed build for Blackberry application.

## J2ME

Currently signing J2ME application's isn't supported. You can use tools such as the Sprint WTK to sign the resulting jad/jar produced by Codename One.
1 change: 1 addition & 0 deletions docs/website/layouts/_default/developer-guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
{{- end -}}
</div>
</article>
{{ partial "crisp-event.html" (dict "function" "gettingStartedDwell" "page" .RelPermalink) }}
{{- end -}}
1 change: 1 addition & 0 deletions docs/website/layouts/_default/getting-started.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ <h2>Build your App!</h2>
</div>
</section>
</div>
{{ partial "crisp-event.html" (dict "function" "gettingStartedDwell" "page" .RelPermalink) }}
{{- end -}}
1 change: 1 addition & 0 deletions docs/website/layouts/_default/pricing.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,5 @@ <h1 class="post-title entry-hint-parent">{{ .Title }}</h1>
</section>
{{- end }}
</article>
{{ partial "crisp-event.html" (dict "function" "pricingEvaluator" "page" .RelPermalink) }}
{{- end -}}
Loading
Loading