Webpart work in Android Sharepoint App but not in iOS Sharepoint App

New Contributor

We have added one custom webpart in Sharepoint online page. The webpart will calling webAPI and displaying the results.

The webpart works fine in IE, Chrome and Safari on desktop and mobile. It works for android Sharepoint App but the data doesn't appear for Sharepoint App in iOS.

Also global navigation is not working for Sharepoint App iOS. Please check below screen.

Details are available on https://answers.microsoft.com/en-us/msoffice/forum/msoffice_sharepoint-mso_imobile-msoversion_other/...

 

Below is the code for your reference

Web API code:

using IntranetServices.Models;
using Newtonsoft.Json;
using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Cors;

namespace IntranetServices.Controllers
{
    [RoutePrefix("api/weather")]
    public class WeatherController : ApiController
    {
        [EnableCors("*", "*", "POST", SupportsCredentials = true)]
        [Route("weatherdata")]
        [HttpPost]
        public async Task<HttpResponseMessage> GetWeatherData(WeatherDataRequest dataRequest)
        {
            HttpResponseMessage httpResponse = null;
            WeatherDataDetails weatherInfo = null;
            try
            {
                var client = new HttpClient();
                string weatherAPIURL = FormatWeatherURL(dataRequest); 
                httpResponse = client.GetAsync(weatherAPIURL).Result;
                if (httpResponse.IsSuccessStatusCode)
                {
                    var weatherContentJSON = await httpResponse.Content.ReadAsStringAsync();
                    dynamic jsonData = JsonConvert.DeserializeObject<dynamic>(weatherContentJSON);
                    weatherInfo = new WeatherDataDetails
                    {
                        ProviderName = jsonData.metadata.provider_name,
                        ProviderURL = jsonData.metadata.provider_url,
                        LocationName = jsonData.countries[0].locations[0].name,
                        LocationState = jsonData.countries[0].locations[0].state,
                        LocationPostcode = jsonData.countries[0].locations[0].postcode,
                        ForecastDate = jsonData.countries[0].locations[0].local_forecasts.forecasts[0].date,
                        ForecastDayname = jsonData.countries[0].locations[0].local_forecasts.forecasts[0].day_name,
                        MinTemp = jsonData.countries[0].locations[0].local_forecasts.forecasts[0].min,
                        MaxTemp = jsonData.countries[0].locations[0].local_forecasts.forecasts[0].max,
                        IconPhrase = jsonData.countries[0].locations[0].local_forecasts.forecasts[0].icon_phrase,
                        IconFilename = jsonData.countries[0].locations[0].local_forecasts.forecasts[0].icon_filename
                    };
                    string jsonResponse = JsonConvert.SerializeObject(weatherInfo);
                    httpResponse = Request.CreateResponse(HttpStatusCode.OK, jsonResponse);
                }
            }
            catch (Exception ex)
            {
                httpResponse = Request.CreateResponse(HttpStatusCode.NotFound, "Weather data not found");
            }
            return httpResponse;
        }
        /// <summary>
        /// construct weather data url
        /// </summary>
        /// <param name="dataRequest"></param>
        /// <returns>weather data endpoint with query parameter</returns>
        private string FormatWeatherURL(WeatherDataRequest dataRequest)
        {
            string weatherApiURL = string.Empty;
            string querystring = string.Empty;
            if (!string.IsNullOrEmpty(dataRequest.LocPostCode))
            {
                querystring = $"&pc={dataRequest.LocPostCode}";
            }
            else if (!string.IsNullOrEmpty(dataRequest.Latitude) && !string.IsNullOrEmpty(dataRequest.Longitude))
            {
                querystring = $"&lat={dataRequest.Latitude}&lon={dataRequest.Longitude}";
            }
            else
            {
                querystring = "&pc=5000";
            }
            string weatherkeyEndPoint = ConfigurationManager.AppSettings["wz:APIEndpoint"];
            string userID = ConfigurationManager.AppSettings["wz:EldersUserID"];
            string passKey = GenerateKey();
            weatherApiURL = $"{weatherkeyEndPoint}/?lt=aploc{querystring}&fc=1&format=json&rollover=24&u={userID}&k={passKey}";
           
            return weatherApiURL;
        }
           
        [Route("{id:int}")]
        [HttpGet]
        public string GetWeather(int id)
        {
           
            return "success";
        }
        /// <summary>
        /// Generate weather zone access key
        /// </summary>
        /// <returns>weather zone access key</returns>
        private string GenerateKey()
        {
            StringBuilder hex = new StringBuilder();
            string weatherAPIAccessPassword = ConfigurationManager.AppSettings["wz:EldersPassword"];
            try
            {
                string genKey = string.Empty;
                string today = DateTime.Today.ToString("dd/MM/yy");
                if (!string.IsNullOrEmpty(today))
                {
                    string[] str = today.Split('/');
                    genKey = Convert.ToString(Convert.ToInt32(str[0]) * 2 + Convert.ToInt32(str[1]) * 300 + Convert.ToInt32(str[2]) * 170000);
                    genKey = string.Concat(genKey, weatherAPIAccessPassword);
                    MD5CryptoServiceProvider md5provider = new MD5CryptoServiceProvider();
                    md5provider.ComputeHash(ASCIIEncoding.ASCII.GetBytes(genKey));
                    byte[] result = md5provider.Hash;
                    for (int i = 0; i < result.Length; i++)
                    {
                        hex.Append(result[i].ToString("x2"));
                    }
                }
                return hex.ToString();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

Model code (return type lass):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace IntranetServices.Models
{
 
    [Serializable]
    public class WeatherDataDetails
    {
        public string ProviderName { get; set; }
        public string ProviderURL { get; set; }
        public string LocationName { get; set; }
        public string LocationState { get; set; }
        public string LocationPostcode { get; set; }
        public string ForecastDayname { get; set; }
        public string ForecastDate { get; set; }
        public string MinTemp { get; set; }
        public string MaxTemp { get; set; }
        public string IconPhrase { get; set; }
        public string IconFilename { get; set; }
    }
 
    [Serializable]
    public class WeatherDataRequest
    {
        public string LocationName { get; set; }
        public string Longitude { get; set; }
        public string Latitude { get; set; }
        public string LocPostCode { get; set; }
        public int NumberofDays { get; set; }
    }
 
 
}

API : http://ws1.theweather.com.au/
it requires USer ID and Password as well 

Home Page code:

 if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(locationSuccess, locationError);
                }

function locationSuccess(position) {
            var latititude = position.coords.latitude;
            var longtitude = position.coords.longitude;
            var weatherRequest = { Longitude: longtitude, Latitude: latititude };
            getWeatherData(weatherRequest);
        }

function getWeatherData(weatherReq) {
            var siteUrl = _spPageContextInfo.siteAbsoluteUrl;
            var weatherApiUri = "https://<azure web App>/api/weather/weatherdata";
            $.ajax({
                type: "POST",
                data: weatherReq,
                url: weatherApiUri
            }).done(function (response) {
                var obj = JSON.parse(response);
                document.getElementById("weatherlocation").innerHTML = obj.locationName + ", " + obj.locationState;
                document.getElementById("mintemp").innerHTML = obj.minTemp + "<span>&#8451;</span>   Min";
                document.getElementById("maxtemp").innerHTML = obj.maxTemp + "<span>&#8451;</span>   Max";
                document.getElementById("forecastday").innerHTML = obj.forecastDayname + ", " + obj.forecastDate;
                document.getElementById("weatherPhrase").innerHTML = obj.iconPhrase;
                var iconFileWithExt = obj.iconFilename;
                var iconfileName = iconFileWithExt.substring(0, iconFileWithExt.length - 4);
             
                $("div#weatherIcon img").attr('src', siteUrl + "/HUB/Style Library/weather/images/" + iconfileName + ".svg");
        
            }).fail(function (jqXHR, textStatus, errorThrown) {
                console.log('Calling weather API failed. ' + errorThrown);
            });
        }

 

 

 

3 Replies
Out of curiosity: What have you used to develop this WebPart and how did you provision to SharePoint?

Web API is developed using VS and deployed/published in AZURE. 

We have used content editor webpart to provision with webpart (added CSOm code in txt file and called same through content editor webpart)