简体   繁体   中英

Get Attribute From Multiple Div Elements into my iOS app from UIWebView W/Swift

How do I get an attribute from a div element defined in my UIWebView into my iOS app?

To explain further...

I have a very simple html document that I load into a UIWebView. It allows a user to click to turn buttons on or off. I set an attribute on the divs to true or false. Refer to my code below.

<html>
<head>
    <title>Tire Selection Template</title>
    <style>
        .front_truck_box{
            display:flex;
            flex-wrap: wrap;
            border:1px solid black;
            height:80px;
            flex: 0 1 80px;
            padding:10px;
        }
        .middle_truck_box, .back_truck_box {
            display:flex;
            flex-wrap: wrap;
            border:1px solid black;
            height:80px;
            flex: 1 1 120px;
            max-width:250px;
            padding:10px;
        }
        .wrapper{
            display:flex;
            flex-direction: row;
            flex-wrap: nowrap;
            align-items:center;
            justify-content: center;
        }
        .tire_box{
            flex: 0 0 10px;
            height:30px;
            width:10px;
            border:1px solid black;
            cursor:pointer;
        }
        .tire_set{
            display: flex;
            flex: 0 0 35px;
            justify-content: space-around;
        }
        .front_tire_set{
            display:flex;
            flex: 0 1 100%;
            justify-content: space-around;
        }
        .first_row,.second_row{
            display:flex;
            flex: 1 0 100%;
            flex-direction: row;
            flex-wrap: wrap;
            align-items: center;
            justify-content: space-around;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="front_truck_box">
            <div class="first_row">
                <div class="front_tire_set">
                    <div class="tire_box" tire="1" active="false"></div>
                    <div class="tire_box" tire="2" active="false"></div>
                </div>
            </div>
            <div class="second_row">
                <div class="front_tire_set">
                    <div class="tire_box" tire="3" active="false"></div>
                    <div class="tire_box" tire="4" active="false"></div>
                </div>
            </div>
        </div>
        <div class="middle_truck_box">
            <div class="first_row">
                <div class="tire_set">
                    <div class="tire_box" tire="5" active="false"></div>
                    <div class="tire_box" tire="6" active="false"></div>
                </div>
                <div class="tire_set">
                    <div class="tire_box" tire="7" active="false"></div>
                    <div class="tire_box" tire="8" active="false"></div>
                </div>
            </div>
            <div class="second_row">
                <div class="tire_set">
                    <div class="tire_box" tire="9" active="false"></div>
                    <div class="tire_box" tire="10" active="false"></div>
                </div>
                <div class="tire_set">
                    <div class="tire_box" tire="11" active="false"></div>
                    <div class="tire_box" tire="12" active="false"></div>
                </div>
            </div>
        </div>
        <div class="back_truck_box">
            <div class="first_row">
                <div class="tire_set">
                    <div class="tire_box" tire="13" active="false"></div>
                    <div class="tire_box" tire="14" active="false"></div>
                </div>
                <div class="tire_set">
                    <div class="tire_box" tire="15" active="false"></div>
                    <div class="tire_box" tire="16" active="false"></div>
                </div>
            </div>
            <div class="second_row">
                <div class="tire_set">
                    <div class="tire_box" tire="17" active="false"></div>
                    <div class="tire_box" tire="18" active="false"></div>
                </div>
                <div class="tire_set">
                    <div class="tire_box" tire="19" active="false"></div>
                    <div class="tire_box" tire="20" active="false"></div>
                </div>
            </div>
        </div>
    </div>
    <script   src="https://code.jquery.com/jquery-2.2.3.min.js"   integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo="   crossorigin="anonymous"></script>
    <script>
        $(document).ready(function(){
            $(".wrapper").on('click', '.tire_box', function() {
                var tire = $(this).attr("tire");
                var active = $(this).attr("active");
                console.log(active);
                //console.log(tire);
                if( active == "false"){
                    $(this).css("background-color","black");
                    $(this).attr("active","true");
                }else{
                    $(this).css("background-color","white");
                    $(this).attr("active","false");
                }
            });

            function test(){
                return "test"
            }
        });
    </script>
</body>
</html>

You can see it in action here: https://jsfiddle.net/x11joex11/0d92ao80/1/

I'm aware of the the following line of code in swift.

theWebView.stringByEvaluatingJavaScriptFromString("document.documentElement.outerHTML")

This line will return ALL the HTML. Now I could go through this perhaps and parse, but I'm thinking it should be possible since I'm using jquery to run a command to get all the boxes that were clicked. When each box is clicked I change its 'active' attribute to "true" or "false". How do I do this?

For example returning an array with values of the "tire" attribute I have on each div (.tire_box) that is clicked ( "active=true" ).

An answer using jQuery (since I have it on my HTML) or Javascript is ok. Just not sure what to put in the stringByEvaluatingJavascriptFromString() function

Update::

I was able to get the value from 'one' of the tires with this command.

document.getElementsByClassName('tire_box')[0].getAttribute('tire')

I need to be able to get the list of tires selected and do something with it in swift somehow. Not sure best way to do this yet...

Whats interesting is I seem to be able to run jQuery code. I created a function test() in a variable outside javascript with an alert('test') in it in my html and ran this code...

Swift Javascript I ran

$(document).ready(function(){
    test();
});

Added to HTML outside document.ready()

var test = function(){
            alert("test function ran");
            return "test";
        };

on the stringByEvaluatingJavaScriptFromString function and it called the alert but I don't seem to get any result back from the stringByEvaluatingJavaScriptFromString function...just blank?

I wonder just 'how' the function returns the javascript and what do I have to do in the javascript command to make it return something?

After much research I finally figured out the answer. Turns out that stringByEvaluatingJavaScriptFromString will return the result of the LAST statement to be run.

That said I modified my html the following below.

<html>
<head>
    <title>Tire Selection Template</title>
    <style>
        .front_truck_box{
            display:flex;
            flex-wrap: wrap;
            border:1px solid black;
            height:80px;
            flex: 0 1 80px;
            padding:10px;
        }
        .middle_truck_box, .back_truck_box {
            display:flex;
            flex-wrap: wrap;
            border:1px solid black;
            height:80px;
            flex: 1 1 120px;
            max-width:250px;
            padding:10px;
        }
        .wrapper{
            display:flex;
            flex-direction: row;
            flex-wrap: nowrap;
            align-items:center;
            justify-content: center;
        }
        .tire_box{
            flex: 0 0 10px;
            height:30px;
            width:10px;
            border:1px solid black;
            cursor:pointer;
        }
        .tire_set{
            display: flex;
            flex: 0 0 35px;
            justify-content: space-around;
        }
        .front_tire_set{
            display:flex;
            flex: 0 1 100%;
            justify-content: space-around;
        }
        .first_row,.second_row{
            display:flex;
            flex: 1 0 100%;
            flex-direction: row;
            flex-wrap: wrap;
            align-items: center;
            justify-content: space-around;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="front_truck_box">
            <div class="first_row">
                <div class="front_tire_set">
                    <div class="tire_box" tire="1" active="false"></div>
                    <div class="tire_box" tire="2" active="false"></div>
                </div>
            </div>
            <div class="second_row">
                <div class="front_tire_set">
                    <div class="tire_box" tire="3" active="false"></div>
                    <div class="tire_box" tire="4" active="false"></div>
                </div>
            </div>
        </div>
        <div class="middle_truck_box">
            <div class="first_row">
                <div class="tire_set">
                    <div class="tire_box" tire="5" active="false"></div>
                    <div class="tire_box" tire="6" active="false"></div>
                </div>
                <div class="tire_set">
                    <div class="tire_box" tire="7" active="false"></div>
                    <div class="tire_box" tire="8" active="false"></div>
                </div>
            </div>
            <div class="second_row">
                <div class="tire_set">
                    <div class="tire_box" tire="9" active="false"></div>
                    <div class="tire_box" tire="10" active="false"></div>
                </div>
                <div class="tire_set">
                    <div class="tire_box" tire="11" active="false"></div>
                    <div class="tire_box" tire="12" active="false"></div>
                </div>
            </div>
        </div>
        <div class="back_truck_box">
            <div class="first_row">
                <div class="tire_set">
                    <div class="tire_box" tire="13" active="false"></div>
                    <div class="tire_box" tire="14" active="false"></div>
                </div>
                <div class="tire_set">
                    <div class="tire_box" tire="15" active="false"></div>
                    <div class="tire_box" tire="16" active="false"></div>
                </div>
            </div>
            <div class="second_row">
                <div class="tire_set">
                    <div class="tire_box" tire="17" active="false"></div>
                    <div class="tire_box" tire="18" active="false"></div>
                </div>
                <div class="tire_set">
                    <div class="tire_box" tire="19" active="false"></div>
                    <div class="tire_box" tire="20" active="false"></div>
                </div>
            </div>
        </div>
    </div>
    <script   src="https://code.jquery.com/jquery-2.2.3.min.js"   integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo="   crossorigin="anonymous"></script>
    <script>
        var returnToIOS = function(){

            //Calculate which tires are 'active=true' and 'active=false' to the array.
            var tires = [];
            var tireObj = {};

            $(".tire_box").each(function(index){
                tireObj = {};//create new object.
                tireObj["number"] = $(this).attr("tire");
                tireObj["active"] = $(this).attr("active");
                tires.push(tireObj);//add to our tire array the object.
            });

            var jsonString = JSON.stringify(tires);
            return jsonString;
        };
        $(document).ready(function(){
            $(".wrapper").on('click', '.tire_box', function() {
                var tire = $(this).attr("tire");
                var active = $(this).attr("active");

                if( active == "false"){
                    $(this).css("background-color","black");
                    $(this).attr("active","true");
                }else{
                    $(this).css("background-color","white");
                    $(this).attr("active","false");
                }
            });
        });
    </script>
</body>
</html>

Notice the function returnToIOS . I made it so it would return a JSON string with the data I wanted from the template.

Next in Swift I did the following code.

let javascript = "returnToIOS();"
let value = self.theWebView.stringByEvaluatingJavaScriptFromString(javascript)

This will return the JSON string with all the data!

To make this even better, I included a library into my iOS project called Swift Json ( https://github.com/dankogai/swift-json/ )

I then ran these commands.

let data = value!.dataUsingEncoding(NSUTF8StringEncoding)

                let json = JSON(data:data!)

                for tires in json.asArray! {
                    print(tires["number"].asString!+" : "+tires["active"].asString!)
                }

and Wha La I had all my data in a nice array that I can manipulate with!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM