As a community I think we’ve moved passed the need for external websites to get current information for weather for iWidgets. While there is still many (legacy) widgets out there the majority have moved to InfoStats2.  InfoStats2 is a tweak that pulls this info directly from the weather app as well as other information from the system. While providing a great API to retrieve such info.

As with many APIs there are good parts and some bad parts. I will explain how I believe i’ve found a way around some of the bad parts. Since IS2 is called in the context of Cycript it should be handled with care. Cycript is very powerful but i’ve seen it be very unstable. This usually comes when you overload it. It seems that Cycript is best used when only used a little.

 

Back in the beginning of Lock+ I had a terrible time with latency or lag.  Since Lock+ is the first thing you see when your device comes on, it was more susceptible to visibly showing lag.  Although Lock+ loaded much faster than the settings app, it was still not fast enough due to it being the first thing you ever see when picking up your phone.

 

The goal at the time was to get Lock+ to load it’s information before the wallpaper finished “zooming in”.  On an Apple device when the lockscreen is shown the wallpaper will have an animation.  I wanted Lock+ to fully load before this animation was complete. I reached that goal many many months ago.  I did this by removing as much as I could from Cycript as it was the bottleneck.  At this time I really studied the response time of Cycript and realized that I just had it doing too much.  An example of doing to much.

 

Screen Shot 2016-12-27 at 1.26.15 PM

The code snippet above is an example of seeing if the phone is plugged in or not. It then returns a string Charging if it is plugged in. While this looks perfectly fine what should stand out is that this is in type=”text/cycript” you may think there still isn’t an issue, but there is one. Cycript is slow.

 

Screen Shot 2016-12-27 at 1.27.41 PM

 

Here is the updated script. This will perform much better than the previous. It’s not really measurable, but if you have multiple things inside the Cycript tag you will begin to see a big difference that is testable.  It’s always best to use Cycript only for retrieving information, then let javascript to the rest. This includes modifying strings, writing to the DOM, or a simple if/else statement.

 

Now to InfoStats2. I have to say this is a great API and tweak, developed by a great person. I use it on all projects and would say if you aren’t then you should be. What i’m about to say is just what i’ve found over using it.

 

Screen Shot 2016-12-27 at 1.44.09 PM

The script above is a simple widget that shows temp, condition, and city.  As you see there is a lot inside the cycript tag. As we know from previous testing this is slow.  I played with this script for days. Trying to get it to be “better”.  Now you can separate a lot from this script and put it into a regular script tag, but i’ve found out this does nothing. It’s just like it’s still inside the script tag.

 

I was very confused about this, and to this day I have no definite answer. I do know that I can overload this script very easily with a forecast, or maybe a graph and cause a crash. Now that I have something that I can always create a crash with, I can re-arrange it to where I have no crash, then I know that the code is performing better.

 

I did this and I found a solution, and maybe a reason why the code (even while not in Cycript) still acted like it was in Cycript. There is a big component here, that is the callback. This is a block that calls once the weather is updated. This block would always contain everything to do with the weather. We need to know when the weather updates so we can update the DOM elements so it will always be tied to it.

 

This makes me believe that even if a function is in javascript, but is called from Cycript that Cycript adopts the function. Therefore will preform terribly.  I said “Cycript is best used when only used a little.” but now I will change that to: “Cycript is best used when only used a little and never calls a javascript function.”

 

This had me frustrated for awhile. I kept trying different methods but none worked. So I decided to do away with any of IS2 weather callbacks. If I update the weather manually, on an interval, I will know when it happens and when to update my DOM. I also wanted my code to be much cleaner. I knew I only needed a set of information from IS2 and that was to 1. update the weather.  2. gather the information for the weather. This is what I came up with.

 

Screen Shot 2016-12-27 at 1.56.32 PM

 

Crazy isn’t it. I use eval to evaluate the string I pass it.

“The argument of the eval() function is a string. If the string represents an expression, eval() evaluates the expression. If the argument represents one or more JavaScript statements, eval() evaluates the statements.”

 

This actually works and works quite well. I just pass what part I want to the function and it executes it in Cycript to get my information. This passes both of my issues. 1. Cycript doesn’t do a lot and it doesn’t call any javascript functions.

 

Screen Shot 2016-12-27 at 2.01.25 PM

 

Here is the code now to update the weather widget. 1. The cycript, which is not much, just our eval function to call InfoStats. 2. What divs we want to change and what IS2 information we want. 3. The function which will continually update the weather.

 

I really like this code. The only thing I will miss is that weather callback, it just gave it that native feeling instead of using a setTimeout, but I can deal with it as i’ve had 0 issues with this no matter what I put at it.