Giter VIP home page Giter VIP logo

tvmlkitchen's Introduction

TVMLKitchen😋🍴 GitHub license Carthage compatible CocoaPods CocoaPods Build Status

TVMLKitchen helps to manage your TVML with or without additional client-server.

Requirements

  • Swift3.0
  • tvOS 9.0+

Use 0.9.6 for Swift2.2.
Swift2.3 is not supported. Feel free to send PR.

What's TVML?

Please refer to Apple's Documentation. It's a markup language which can be used only on tvOS. TVML makes it easy to build awesome apps for tvOS.

Why ?

TVML is easy, but TVJS is not really. With TVMLKitchen, loading a TVML view is in this short.

Kitchen.serve(xmlFile: "Catalog.xml")

You don't have to write any JavaScript code at all!

Kitchen automatically looks for the xmlFile in your Main Bundle, parse it, then finally pushes it to navigationController. Please refer to the Documentation for more information.

Available Features

  • Load TVML from URL.
  • Load TVML from raw XML String.
  • XML syntax validation API
  • Multi UIWindow Support
  • TVML Recipe Protocol

Examples

Installation

Carthage

Put this to your Cartfile,

github "toshi0383/TVMLKitchen"

Follow the instruction in carthage's Getting Started section.

Cocoapods

Add the following to your Podfile

pod 'TVMLKitchen'

References

For implementation details, my slide is available.
TVML + Native = Hybrid

Contribution

Any contribution is welcomed🎉

tvmlkitchen's People

Contributors

anthonycastelli avatar lukaskuster avatar steve228uk avatar toshi0383 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tvmlkitchen's Issues

serve(urlString:) should accept errorHandler closure

If serve(urlString:type:) or serve(urlString:... for multi window... ) fails, currently there is no way to recover.
User will be left with current screen (or empty Kitchen.window for multi window case).

The new error handler should be called on

  • XML parse error
  • Network error

I don't think of other errors than above, but if there are other kind of errors, they will be ignored.
Note that all errors are reported to Cookbook.onError.

Move from UIKit ViewController to a Kitchen.serve view

Hello!

I am really interested to use this library as this makes much more sense to me than using the storyboard editor coming with Xcode.

That being said, I have an established project currently and I'm trying to integrate this into the mix.
Here is what I've done so far.

I map the movies to a structure using the Object Mapper piece (still needs cleanup)

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        let movie: Movie = Mapper<Movie>().map(self.movies[indexPath.row].rawString())!
        let product = MovieProductRecipe(movie: movie)
        print(product)
        self.view.hidden = true
        Kitchen.serve(recipe: product)
    }

The collection view is a delegate coming from the storyboard which is referenced via drag and drop methods.

Next piece I want to do is serve that to the screen. Which it works! But I'm pretty sure according to tvOS' focus engine it is just not focusing on the element being display. As if this doesn't exist in the navigator.

Do I need to put something within my recipe to get this to work?

So would I need to rewrite my entire project using this library and depend on library that heavily? Or is there a way to pull focus into the mix. Thanks for the help and amazing library, its awesome what you can do with this.

Tab Reloading

It's me again! Another feature request if it doesn't already exist haha.

Is there currently a way to reload a view in a tab? What Im after is either being able to tell a tab to reload its data or when the tab is loaded each time fetch the data it needs. Does something like this exist that I can use? If not what would be the best route to implement something like this?

TVML's view is reloadable ?

In apple's sample-code, search template is reloading thumbnails dynamically.
Looks like there is a way to do this, and I will look at it later.

Search Recipe Grid option

Could you add in a grid option for search results? Having it as a default option might be a better choice considering a search could return a large amount of data. A section just scrolls in a horizontal fashion.

Remove Kitchen.serve(jsFile:) API

Created this issue so this breaking change is noticeable for everyone.

I decided to remove this API to keep things simple.
I assume nobody would do fancy things in their jsFiles via TVMLKitchen anyways.

Please open a feature request if really need to specify jsFile path and let TVJS to evaluate them.

Swift 4

Hey there. I would really like to use TVMLKitchen in conjunction with my swift code but there is no support for swift 4. If possible, can you update your code for swift 4. I'd be more than happy to pilot your code.

1.0.0 Milestones

After migrating to Swift3, I'm planning to bump version to 1.0.0.
Feel free to comment if you come up with something.
Release will be in later this year.

v1.0.0 cocoapod is not being recognized as Swift 3.0

I've updated my pod to v1.0.0 to get the Swift 3.0 version. The framework will not compile with my Swift 3.0 project, as Xcode still recognizes TVMLKitchen v1.0.0 as Swift 2.2.

As a note, I've taken the source from the Swift 3.0 branch and included it directly in my project, and everything works fine. This seems to be an issue with the cocoapod itself.

Remove __kitchenDebug function calls

Should be removed for performance reason.
Although actual printing does not happen unless DEBUG is set to OTHER_SWIFT_FLAG, the injected function __kitchenDebug is still called.

SwiftLint Run Script Build Phase fails on `carthage update`

Oops.

$ carthage update
config error: 'variable_name_min_length' is not a valid rule identifier
/Users/toshi0383/dvideo/tv/app/Carthage/Checkouts/TVMLKitchen/source/TVMLBridging.swift:31:36: warning: Variable Name Violation: Variable name should be between 3 and 40 characters long: 'js' (variable_name)
config error: 'variable_name_min_length' is not a valid rule identifier
/Users/toshi0383/dvideo/tv/app/Carthage/Checkouts/TVMLKitchen/source/TVMLBridging.swift:31:36: warning: Variable Name Violation: Variable name should be between 3 and 40 characters long: 'js' (variable_name)

Missing Product Recipe

Howdy!

I've been working on some recipes for the Product and Descriptive Alert templates. Once completed, did you want me to submit a PR?

I'm also not sure of the best approach in handling actions. Is there a way for a recipe to intercept these or is it one global handler for the application? Currently I'm using the following:

func actionIDHandler(id: String) {
   switch id {
   case "showDescription":
       DescriptionRecipe.show(selectedMovie)
       break
   default:
       break
   }
}

My approach in generating the XML is slightly different to yours too and I'd appreciate your opinion on whether this is a good idea or not. I have an XML file called product.xml that has placeholders such as {{TITLE}} and {{DESCRIPTION}}. These are then replaced to generate the final template with the following:

public var template: String {
    var xml = ""
    if let url = NSBundle.mainBundle().URLForResource("product", withExtension: "xml") {
        xml = try! String(contentsOfURL: url)
        xml = xml.stringByReplacingOccurrencesOfString("{{DIRECTOR}}", withString: director)
        xml = xml.stringByReplacingOccurrencesOfString("{{TITLE}}", withString: title)
        xml = xml.stringByReplacingOccurrencesOfString("{{ACTORS}}", withString: actorString)
        xml = xml.stringByReplacingOccurrencesOfString("{{DESCRIPTION}}", withString: description)
        xml = xml.stringByReplacingOccurrencesOfString("{{IMAGE}}", withString: image)
        xml = xml.stringByReplacingOccurrencesOfString("{{YEAR}}", withString: year)
    }
    return xml
}

simulator screen shot 14 mar 2016 00 51 09
simulator screen shot 14 mar 2016 00 51 03

Presenting the tabBar from an Action

Currently there isn't a way to present the TabBar via Kitchen.server() or via by giving KitchenTabBar a presentation style. Any chance of getting something like this implemented?

UIViewController into a UITabBar

Maybe I'm overlooking something but i've gone through the framework and can't seem to find anything that would allow me to add UIViewController to a UITabBar. Is this currently not possible?

dyld: Library not loaded: @rpath/libswiftSwiftOnoneSupport.dylib

Environment

macOS Sierra 10.12.4 (16E195)
Xcode 8.3 (8E162) (Confirmed repro on Xcode8.2.1 too)
Carthage 0.20.1

Reproduce Step

  • carthage update --platform tvOS
  • Add carthage copy-frameworks build phase
  • Open App.xcodeproj and Cmd + R, this runs with no problems.
  • Close xcodeproj and Create a new xcworkspace including the App and TVMLKitchen xcodeprojs.
  • Open the xcworkspace and Cmd + R, the error occurs.

tvmlkitchen-142

Log

dyld: Library not loaded: @rpath/libswiftSwiftOnoneSupport.dylib
  Referenced from: /Users/toshi0383/Library/Developer/Xcode/DerivedData/HelloKitchen-ejgwzgjuarttagdecndevauvhuqx/Build/Products/Debug-appletvsimulator/Himotoki.framework/TVMLKitchen
  Reason: image not found

Solution

Add ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES to buildSettings which is currently NO.

"Inalid Segment Alignment" when uploading to iTC

When I'm trying to upload to iTunes Connect I got a "Inalid Segment Alignment" error:

"Inland Segment Alignment. The app binary at '....TVMLKitchen.framework/TVMLKitchen' does not have a proper segment alignment. Try rebuilding the app with the latest Xcode version."

I've downloaded & installed v0.7.1 using Carthage.

Nothing Displays

This must be something to do with my setup but when I call Kitchen serve nothing gets displayed.

Here is what I get in the console:

App[13589:5955308] ITML <Error>: Unable to create elements for document <alertTemplate itmlID="id_2"><title>test</title><description>DESCRIPTION</description></alertTemplate>
App[13589:5955091] #T:[Main] #Notice #SYSTEM : Template element: (null) 
2016-06-15 21:11:17.498 

Here is the code from the AppDelegate.

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    let cookbook = Cookbook(launchOptions: launchOptions)
    Kitchen.prepare(cookbook)
    Kitchen.serve(xmlFile: "alert.xml", type: .Modal)
    return true
  }

I'm using a slimmed down template with pretty much nothing in it. But even the built in recipes do the same thing.

PlayActionHandler

Currently actionHandler handles only "select" event.
We should add handler for "play" event, so user can start playing from list view.

"Unsupported Architectures" when uploading to iTC

I'm trying to upload my new & shiny tvOS app to iTunes Connect. But unfortunately I retrieve the following error on upload:

"Unsupported Architectures. The executable for ... TVMLKitchen.framework contains unsupported architectures '[x86_64]'".

I've downloaded & installed v0.7.1 with Carthage. Any Idea whats wrong?

Handle openURL

<lockup
     open-url="https://itunes.apple.com/jp/app/idnnnnnnnnnnnn?mt=8"
>

Handle open-url in kitchen.js load function.

Modal presented TVML should be dismissed when it opens other TVML using template attribute

TVML should be dismissed when presented modally, and opening other TVML.

Current Behavior

I can present a TVML modally like this. (Thanks a lot @steve228uk !)

Kitchen.serve(jsFile: "Sample.xml.js", type: .Modal)

Sample.xml.js has a button like this.

<button class="button" template="https://raw.githubusercontent.com/toshi0383/TVMLKitchen/master/SampleRecipe/Catalog.xml.js">

If this is clicked, kitchen.js presents the Catalog.xml.js behind the Sample.xml.js .

Any movie playback feature ?

Personally I've never done any movie playbacks in TVML.
I have questions like below.

  • Is FairPlay Streaming Supported ?
  • Is FairPlay Streaming available in inline playback (tvOS10+) ?
  • Is any other DRM (Widevine, PlayReady...) supports possible ?
  • How could I interact with video UI using TVInterfaceCreating (tvOS10+) ?

Will investigate on these later...

"UIMainStoryboardFile" setting conflicts with Kitchen

Problem

If Info.plist's UIMainStoryboardFile is set, the app happen to have 2 UIWindows in parallel.
Either one who is keyWindow gets focused.

Currently Kitchen holds its own UIWindow in private sharedKitchen instance, and uses it to create a TVApplicationController instance.
See: https://github.com/toshi0383/TVMLKitchen/blob/swift2.2/Sources/Kitchen.swift#L264
Looks like this UIWindow conflicts with UIMainStoryboardFile's UIWindow.

Expected

The app have one UIWindow and Kitchen will share that instance.
That's said, Views appears in same view hierarchy, not in parallel in different windows.

Possible solutions (Investigation Needed)

  1. Detect other UIWindow existence in prepare phase and yell out that something is wrong.
  2. Add capability to pass a specific UIWindow instance to Kitchen, so Kitchen can use it to instantiate a TVApplicationController in prepare phase. (Don't know if it works)
  3. Make Kitchen's UIWindow always on top. (Maybe configurable via windowLevel property?)

Can it play videos?

Hello,

I use SampleRecipe in my Swift tvOS app. It can load TVML file from raw XML String, however it can't play videos?

Anyone knows how to solve it? Thanks!

btw, happy new year!

.reloadTab Not Allowing for ActionID

Hey man!

Came across a small issue that I'm looking into now but simply put this:
Kitchen.reloadTab(atIndex: 1, recipe: CatalogRecipe(title: self.title, movies: movies))

prevents actionID's from within the XML to work. I'm trying to figure out why now. If you have any information on this that would be awesome!

Thanks!

How to dismiss Button after popping up TVML view?

Hello there,

I try to use TVMLKitchen last week. This is a really awesome tool to help with tvOS development.

I create a Button in a screen, after clicking the Button, another TVML will be pushed into screen. However, the Button is still in the screen, which is really annoying.

I don't know how to dismiss this button, anyone has any ideas? Thank you!

simulator screen shot dec 7 2016 11 05 45

Here is my code for your reference.

class TestViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func test(sender: AnyObject!) {
        Kitchen.serve(xmlFile: "Oneup.xml")
    }
}

Add a way to manually show/hide loading

When running async requests in UIKit it would be good to have a way to show/hide the loading screen.

Potential Solutions

  1. A computed property called loading. This would be executed as the following:
Kitchen.loading = true
Kitchen.loading = false

var kitchen: Bool {
    didSet {
        // Show/hide the loading screen based on the new value
    }
}
  1. Show/hide loading methods
Kitchen.showLoading()
Kitchen.hideLoading()
  1. A 'replace' presentation style (I feel this should exist anyway). This will replace the current view in place and is already be used in kitchen.js for the default loading screen.
Kitchen.serve(xmlFile: "loading.xml", type: .Replace)

The benefit of this is that the user can also customise the loading.xml to be whatever they want/need. This could also be a recipe with a title property.

Proposed Solution

My suggestion would be to utilise both the property and new .Replace presentation types together to give the developer the most flexibility.

XML Validate API

It would be convenience if Kitchen has XML validation API, so users can check if the xmlString is valid before calling Kitchen.serve(xmlString:).

Here is general idea.

let xmlString = // string which is to represent TVML.
do {
    try Kitchen.verify(xmlString)
    Kitchen.serve(xmlString: xmlString)
} catch let error as TVMLDecodeError {
}

or it can be like this way.

let xmlString = // string which is to represent TVML.
do {
    try Kitchen.serve(xmlString: xmlString)
} catch let error as TVMLDecodeError {
}

The latter one would be a breaking change, so I think we should stick with the first one(throwing verify method).

SearchRecipe.swift @escaping callback block.

Could you please mark override func filterSearchText(_ text: String, callback: ((String) -> Void)) callback block as @escaping.

If a user is fetching search results from a remote API (very likely) the compiler rightly flags that the callback parameter could have escaped by the time remote API has responded.

Custom HTTP Header

We should make HTTP Header fields customisable when Kitchen requests TVML on Network.
Workaround for now is to send network request by yourself, then pass the response XML string to Kitchen.

Showing Description Issue

Hello @toshi0383, I'm not sure if you have noticed.

In MoviePlaybackSample or other sample, the app can't open the long description in a separate screen. As the picture below shows,

1

Ideally, it should show like this way.

2

I realized there is a still open issue#27 talking about this problem, which is #27 .

I think there is a missing actionIDHandler to deal with opening a long description. I will try to solve this issue following steve228uk and your thoughts in #27.

If you have any further ideas about this issue, could you please leave here? I gonna follow up, and submit an PR after completing. Thank you! 😀

How to load local files embedded in Template?

How may I add local files (from the main bundle) to a xml template?

For example, I'd like to provide a static menu, the user can choose an item by using the stackTemplate.
For each menu Item I want to show a logo, served locally and stored in the main bundle.

For each entry I got a code similar to this:

<lockup>
    <img src="wordpress.png" width="548" height="274" />
        <title>WordPress</title>
</lockup>

And the image wordpress.png is stored in the main bundle - but as you can see on the following screenshot it isn't displayed:

simulator screen shot 14 05 2016 17 44 13

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.