Wrapping – Export Hype HTML to an App 🎁

TL;DR – Wrapping is now available at Etsy

HYPE EXPORT SCRIPT INCLUDED! :sunglasses:

"Wrapping" is an App that neatly exports your Hype HTML (or HTML project in general) to a Mac or iOS "WKWebView" Xcode project. In five easy steps, your HTML project can be ready to export as an app.


Wrapping (Export Script) Video

This is an unedited video of Wrapping, as a Hype Export Script, in action. You can even see me getting bored while Xcode is building. :blush:

But even with that, the whole process is less than 1:17 seconds!

Here's the same process with the Wrapping app...


Historical Conversation...

I'm posting my notes about my Hype HTML to Xcode Webview project because I'm abandoning it. I'm not having fun with it and I'm not seeing a real need for the end product. It's just too easy to drag-and-drop HTML into an already existing Webview project. Yet, I learned a lot, so it might be interesting to you...

A few years ago, Apple introduced JavaScript for Automation. It's kinda like AppleScript and JavaScript made a baby. Basically, you can leverage your existing JavaScript knowledge to automate tasks on your Mac. Here's the introduction video from WWDC 2014...

I was like... whoooaaaa... that's cool! But like the Mac Mini, it's future is uncertain. Sal Soghoian's job was eliminated... https://9to5mac.com/2016/11/17/mac-user-automation-sal-soghoian/ ...Craig Federighi says Apple intends to keep supporting automation... http://www.macworld.com/article/3143093/macs/apple-s-craig-federighi-every-intent-to-support-automation-in-macos.html ...but I haven't seen much development since 2014.

You can clearly see this is a problem by the lack of JXA documentation around. This... https://github.com/JXA-Cookbook/JXA-Cookbook ...and parts of this... https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/index.html ...is pretty much it.

So yeah, so maybe I should have just used Python, like Tumult does... https://github.com/tumult/hype-export-scripts ...but then I realized a big problem with the Hype Export API. For this project, it's probably better not to use it.

Regardless if I wanted to sell the html-to-code script, it's ideal to reach the most amount of people. Export Scripts – that's a feature limited to Hype Pro... http://tumult.com/hype/pro/ ...so it's just better to take an exported project and plop it into an Xcode Webview project, where there is no limitation. (Theoretically, an external script would even work with a regular HTML folder. Hype is not required at all.)

It would be nicer to export straight from Hype, but what does that really save... five seconds?! I've wasted a lot of time trying to get this to work. Do people really need a script for this? No, it's drag-and-drop. Plus, there's the whole, "Hey dude, Apple rejected my app. Your script sucks!"

Anyway, here's what I learned...


In addition to running JXA in the "Script Editor" app or "Automator", both included with current versions of OS X, you can run JXA straight from the terminal...

#!/usr/bin/env osascript -l JavaScript

That's how I was able to use JXA, instead of Python, in Hype. Yet, I thought a separate app would be better. So, a lot of what you do depends on what app you're working with. (I got lots of security errors trying to use the Finder.)

You can target a specific app by using it's name. (The WWDC video explains this.)

app = Application('Hype') // Access application By Name

You can also just use the current application. (This works well when using Script Editor.)

app = Application.currentApplication()
app.includeStandardAdditions = true

In JXA, you're manipulating the desktop rather than DOM elements. I could use JXA to do a lot of silly stuff...

app.beep(1) // Play Alert Sound
app.say('Hi!') // Text-to-Speech
app.displayAlert('Hi!') // Display Alert

That's why the "includeStandardAdditions" part is important.

So, then I actually got real things happening. I could have it pop-up a window, where a directory could be chosen. Then, that directory would be optimized with ImageOptim.

loc = app.chooseFolder()
console.log(loc)

app.doShellScript (`if open -Ra "ImageOptim.app"
then
/Applications/ImageOptim.app/Contents/MacOS/ImageOptim ${loc}
fi`)

What's nice is that it checks if ImageOptim is on the computer. If it's there, then it runs. I was using the location from one part of the script and adding it to another part of the script.

That's where I stopped. I was like, why would I do this? There are so many things to check for. What if you want to update an existing Xcode project with a change to the Hype project? How would settings be determined? Why optimize the same images over and over, should I just optimize them in the Hype project?! What if that ruins their only copy of the image?

There were too many issues and not a lot of fun, so that's why I gave up on it.

4 Likes

I was exactly the same and then ..bum..

I have notice a bit more on the docs in the developer site but still not much..

This was exactly the same problem we had with ScriptingBridge

I still find I do most of my Automation in AS and Unix combined.

The other thing that got me wwas Apple not even fixing the bugs they introduced in their own Scripting Libraries/Events for their Apps.!!. One of which broke a great Automator Action I had written. And still is broken because of a bug that only Apple can fix.

I know a lot more JS than I did when JXA was introduced so I may at some poit go back and look at it.

Thanks for the write up - sorry to hear you are not continuing the project!

1 Like

There’s a small possibility that I’ll be restarting this project again. I started testing WebKit again today and I realize – wow, this is tedious. A script would be useful, even if it’s a one-shot export.

If you know any objective -c, I would suggest using that within the Applescript JXA. JXA/Objective - c Hybrid.

I have been playing with JXA a bit of late so I can read IPTC headline tag and use that to rename file names.

My initial script JXA only , included do shell with exiftool.

About a thousand files took about 5-10 mins to process. Really bloody slow.
Mainly because the do shell but also the complexity of the JXA routines.
So I rewrote it again within JXA but also bridging Objective - C. The Objective - C replaced all the shell calls and the use of third party libs. And many of the Javascript code.

It was much more simpler to write doing this. And the rename of the file names for example 4000 files takes all of 30-45 seconds. Wow.

So I know speed will not really be an issue for you but maybe using JXA/Objective -C may make it easier to write.


Also can you layout what your goals are for the script to do…
Maybe we can suggest or help with a bit of the code …

1 Like

Maybe it could be an Open Source project. :thinking:

TL;DR – It takes a Hype project and wraps it in a WKWebView

UPDATE: I’m planning to release this as an app called “Wrapping”, as the idea is to neatly wrap your Hype (or regular HTML project) into a WKWebView. I’m not entirely sure if I can complete this app idea, but I’m closer than I was yesterday. “Wrapping” is now the target for app #3 of the 10-Year plan.

2 Likes

I’m getting closer, here’s what’s new…

  1. I dropped JXA in favor of AppleScript.
  2. It automatically creates the many icons for the Mac and iOS apps, from a 1024x1024 source image.
  3. The “Wrapping” App Icon is done. I think it’s cute.

256

2 Likes

I’m getting curious.

2 Likes

I’m really curious…

1 Like

It is a riddle, wrapped in a mystery, inside an enigma…

1 Like

Cute icon. I don’t know if it will help you, but I did come across this article today:

https://useyourloaf.com/blog/creating-custom-xcode-project-templates/

3 Likes

Great Find

Are we there yet?

Well, the following was generated from the "Wrapping" code...

18 AM

It doesn't actually work, but that's the next step. If all goes well, "Wrapping" should be on the Mac App Store by the end of this week. That's the goal anyway.

That's what I said. :smile:

I'm using a different method to create the Xcode project. It might work, it might not. That's what's fun and frustrating about web/app development.


UPDATE: I made lots of progress, but I hit a wall. I'm pulling out the big guns. I'm using one of my Apple Technical Support Incidents (TSI) – Requesting Technical Support - Support - Apple Developer – I get two with my 1-year Apple Developer Membership. This seems an appropriate use of a TSI though, as it appears to be the only problem left.


ANOTHER UPDATE: Wall smashed. I figured it out before Apple responded. But of course, there are more puzzles to solve. Overall, the progress is looking good. If you are curious as to what the problem was, it was "File Reference" in the project.pbxproj file. I didn't know what those 24 character codes were...

Apparently, those codes are not really important... not for this particular project. The problem was that I was saving the .xcodeproj in the wrong place. Heh!

4 Likes

Gentlemen, and ladies, break out your Star Wars: Episode 1 memes…

It’s Working!

57 PM

So, it’s kinda a funny story as to why this wasn’t working before. Remember when I said I was trying a different method to create the project? Well, I found a great document on Stack Exchange…

I’m like… awww… how cute. There’s a “cat” command. So, I figured I’d use “:cat:” as the way to mark the End of File. Yeah… bad idea. A lot of stuff was dropping out of the info.plist. I then realized I needed to escape the dollar signs.

…but the fix wasn’t working because the emoji was preventing it. So, while cute, it might not be a good idea to use emoji in your code. It wasn’t a good idea in this case – other than being quite funny! :smile:

So, what’s left?!

  • Move AppleScript code into Xcode (This is going to suck!)
  • Further personalize the generated code. Lots of “Photics” references in there.
  • See if I can auto select the developer team. While the project works, it won’t run until a dev team is selected. “Signing for <app.name> requires a development team.
    Select a development team in the project editor.”
  • Actually move HTML from a Hype project into the “html” directory inside the “Wrapped” folder.
  • Mac is first, I might launch with just that. iOS is next… maybe… MAYBE… I’ll add Android and even Window support. The latter two are definitely a ways out though, certainly not a launch item.

I’m feeling really good about this project… like REALLY good. This is a moment in time that’s special. It could be a huge boon for the popularity and success of both Tumult and Photics… and the people that use the app too!

It’s ridiculously easy now to “Wrap” a Hype project as an app. So much tedium is eliminated! Of course, that means the Hype project has to be designed for mobile, but that’s where Hype excels. “Wrapping” is the missing piece of the puzzle.

I will continue to work hard on this project. This is an exciting week!

3 Likes

Wow, that sucked! I underestimated one particular (and very important) piece of Mac App Store Development – Sandboxing! Heh, I should have known something would go wrong. I was feeling too good.

I was highly tempted to give up, but this project is too important. I don't want to let you down.

See... that's disappointment...

But... with perseverance... we have the opposite of disappointment...

14 PM

Quite frankly, I was surprised to see that screen. I had to be extremely creative with getting around the sandbox limitations. I'm still not sure if Apple is going to green light this app. If they don't, all is not lost. I can still sell the app though FastSpring. I'm probably going to do that anyway.

For version 1.0 – it's just Mac wrapping. I figure I should wait and see what Apple does before I go nuts coding the iOS part. Apple has been pretty fast with reviewing apps lately. So, it is conceivable that the "Wrapping" app could be online this week.

Sandboxes should be fun. It turns out they are the last layer of mac hell. At least there are fewer layers on the mac :wink:.

Are you having any beta testing before launching?

TestFlight would have been great for this, but it’s not on macOS.

Apple rejected the app. They didn’t like the security exceptions. It’s late in the day for me, so I’m not sure what to do next... besides sleep. Ha ha. This app is looking better suited for FastSpring.


UPDATE – OK, my day started out as expected. I fired off a bunch of semi-angry emails to Apple. Then, I went to shower. So there I was, standing there, nice warm water, it hits me. I can totally bypass this bureaucracy – and get my app approved! It involves using Wrapping to make the Wrapping app. There was much maniacal laugher, so it must be a good idea.

More info should be available soon! :slight_smile:


ANOTHER UPDATE – Wow, what a wasted day. So, I figured I'd just use a WebView to download a custom AppleScript. It wasn't ideal, but I thought it would do the job...

https://bugs.webkit.org/show_bug.cgi?id=174076

...nope! It creates the AppleScript, but it doesn't download it. The code just stays in the window. I supposed there is a bright side to this. Every pitfall I hit is a potential pitfall for future customers. I'm learning more about the boundaries in Apple's Walled Garden.

Not sure how to get this app on the inside at the moment. Currently, there are three possibilities...

  • Rewrite the app in Swift
  • Wait and see what Apple says about the emails I sent them. (I got one reply so far, which basically said stop sending so many emails. HA HA!)
  • Screw it, release the app through FastSpring
1 Like

I’m unclear on what you’re exactly trying to do?

Can you just use the app itself to save a file to disk?
(also I’ll note that Hype itself doesn’t use a WKWebView for its main editor as it is too limited. Sometimes the old school WebView is the way to go).

In the original idea, the files are modified, based on what people put into the app. It's basically creating the whole Xcode project, with lots of nice changes for WKWebView.

It works great, until you turn on Sandboxing.

So, I tried making a WKWebView app to allow downloads. It was like nope. It loads the code as if it's a web page.

I did try a regular WebView, which took much longer than I thought it would to create. I forgot how to do it. HA HA. Anyway, that version looks like this...

01 PM

...but instead of generating the code, it saves the following to a file...

+ encodeURIComponent(scriptStream) +

It basically ignores the "octet-stream" part...

document.getElementById('save').innerHTML = '<a download="wrap.scpt" href="data:application/octet-stream,' + encodeURIComponent(scriptStream) + '"><button style="height:100%; width: 100%; border-radius: 5px; background-color: #eee; font-size: 14px;">Save Script</button></a>';

I liked that idea, as then I could theoretically create two versions of the script... one for general use and one for Hype Export Scripting. (Heh, I'm no where near at solving the latter right now, as I still don't quite understand how it works. My script works very well, it does almost everything it's supposed to, but I'm not sure how it would play nice directly inside Hype.)

So, today, I started learning more about Swift. It's actually a nice programming language. While I like AppleScript version, the Swift version of this app is pretty good too. It's stronger than the AppleScript version in some areas. It's nice to have native code. Unfortunately, I keep running into the same sandbox permissions problem. I thought I was able to write a file to the downloads folder, so I'm not sure what happened...

My next step is to try this tutorial again...

...as I thought I was able to write files, but now it's not creating directories . Swift is nice, but it's too verbose. It's not something simple like "create directory"... no... it looks like this...

let mainPath = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first!

func createDirectory(pathy: String) {
    let dataPath = mainPath.appendingPathComponent(pathy)
    do {
        try FileManager.default.createDirectory(atPath: dataPath.path, withIntermediateDirectories: true, attributes: nil)
    } catch let error as NSError {
        print("Directory Error: \(error.localizedDescription)")
    }
}

createDirectory(pathy: targetPrefix + appName)

NSblahblahblah... such nonsense terms in ObjectiveC and Swift. Anyway, I created a function to create directories, as there are a lot of directories to create. Again, works well – until sandboxing is turned on.

I told the engineer support to hold off, as there are too many issues. They're not going to convert my whole project to Swift, so I figured I'd try to get as close as possible.

My concern is that they'll phase out the regular WebView eventually. Also, WKWebView is supposed to have speed enhancements. It's absurd how much changes with Swift... and each upgrade seems to make some things even more complicated to do. (The multiline variables are nice though, so I've been using Swift 4, which means I can't use my trusty early 2009 Mac Mini.)


UPDATE – Nope, the sandbox just breaks File/Folder creation – even if I use read/write for the "Downloads" directory. I sent out more information for the Apple Engineers. I'm not sure what they'll say.

At first I was really frustrated, but then I thought... what would I be doing if not this? I'd probably be wasting time watching TV. Heh. So, I can try to figure out this problem... while watching TV.