Shouldn't wrapped optionals always print with the keyword 'Optional'? - swift

Code
func downloadimages (URL: NSURL) {
let request = NSMutableURLRequest ( URL: URL)
request.HTTPMethod = "GET"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error ) in
guard error == nil else {
print("we have an error from Server")
return
}
var JSONData: AnyObject!
do {
JSONData = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) /* as? [String:AnyObject?] */
} catch {
print (" We had a Parsing issue '\(data)'")
return
}
print(JSONData)// Doesn't print 'Optional' word?????
print(JSONData!)
if let something = JSONData!["photos"]{
print (something!)
print(something) // This prints the word 'Optional as well'
}
Output
//printed unwrapped--NOT GOOD! -- I didn't unwrap it with '!'
{
photos = {
page = 1;
pages = 622374;
perpage = 1;
photo = (
{
farm = 8;
id = 27765969370;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = "8262787#N07";
secret = 6daeee7d68;
server = 7233;
title = "Stars, Planets and Lightning Bugs";
}
);
total = 622374;
};
stat = ok;
}
// unwrapped printed--Good!
{
photos = {
page = 1;
pages = 622374;
perpage = 1;
photo = (
{
farm = 8;
id = 27765969370;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = "8262787#N07";
secret = 6daeee7d68;
server = 7233;
title = "Stars, Planets and Lightning Bugs";
}
);
total = 622374;
};
stat = ok;
}
//Unwrapped printed--Good
{
page = 1;
pages = 622374;
perpage = 1;
photo = (
{
farm = 8;
id = 27765969370;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = "8262787#N07";
secret = 6daeee7d68;
server = 7233;
title = "Stars, Planets and Lightning Bugs";
}
);
total = 622374;
}
//wrapped and prints as optional--Good!
Optional({
page = 1;
pages = 622374;
perpage = 1;
photo = (
{
farm = 8;
id = 27765969370;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = "8262787#N07";
secret = 6daeee7d68;
server = 7233;
title = "Stars, Planets and Lightning Bugs";
}
);
total = 622374;
})
My confusion is, if JSONData is an optional then why does it print as non-optional without ! and if it isn't an optional then why doesn't it give any error as Can not force unwrap value of non-optional type?. Since unwrapping a non-optional is error-ful!
My guess is that I am not understanding what my JSONData's type really is...

My guess is that I am not understanding what my JSONData's type really is...
I believe that is the point.
You've declared JSONData as AnyObject!, which is also known as ImplicitlyUnwrappedOptional<AnyObject>.
So, in your code print(JSONData), the value of JSONData is implicitly unwrapped.
And check the type of something in the Quick Help pane of your Xcode. It should be displayed as AnyObject?, aka Optional<AnyObject>.
One bad thing is that when implicit unwrapping occurs it doesn't get well-documented. You may need to know more about ImplicitlyUnwrappedOptional, before knowing exactly when that happens.

Related

VSCode language extension with hierarchical Outline, DocumentSymbol

I'm trying to get outline working with a custom language in VScode. I have the below code but I feel like it is slow because of the way I find a range in class. Are there better ways to find the range and assign children. I've thought about just keeping track of the depth of the brackets and assigning all functions/methods/classes in higher depths into the last item of previous depth.
It was based off of this answer.
class JSLDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(document: vscode.TextDocument,
token: vscode.CancellationToken): Thenable<vscode.DocumentSymbol[]> {
return new Promise((resolve, reject) => {
var symbols: vscode.DocumentSymbol[] = [];
var depth = 0;
for (var i = 0; i < document.lineCount; i++) {
var line = document.lineAt(i);
var txt = line.text;
var ltxt = txt.toLowerCase();
let open_brackets = ltxt.match(/\(/g) || [];
let close_brackets = ltxt.match(/\)/g) || [];
// console.log(ltxt)
// console.log(open_brackets, close_brackets)
//console.log(i, open_brackets.length, close_brackets.length)
depth += open_brackets.length - close_brackets.length;
//console.log(depth);
if (ltxt.includes("define class(")) {
let sname = txt.trim().substr(14, txt.trim().length - 16); //this is hard coded right now but it's kind of working
let detail = "ARGS:x, y returns z";
let start_pos = new vscode.Position(i, 0);
let n_bracket = 1;
let i_char = 0;
//let children: vscode.DocumentSymbol[] = []
let ds = new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Class, line.range, line.range);
for(var i_line = i; n_bracket > 0; i_line++){
let class_line = document.lineAt(i_line);
let mtxt = class_line.text;
let ic;
if(i == i_line) ic = 16;
else ic = 0;
for(i_char = ic; i_char < mtxt.length; i_char++){
if(mtxt[i_char] === "(") n_bracket++;
else if(mtxt[i_char] === ")") n_bracket--;
if(n_bracket === 0) break
}
if (/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i.test(mtxt)) {
let result = mtxt.match(/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
let mname = result[1].trim();
let m_details = ""
if(result.length == 3){
m_details = result[2].trim();
}
ds.children.push(new vscode.DocumentSymbol(mname, m_details, vscode.SymbolKind.Method, class_line.range, class_line.range));
}
if(n_bracket === 0) break
}
let end_pos = new vscode.Position(i_line, i_char);
let rng = new vscode.Range(start_pos, end_pos);
ds.range = rng;
//ds.children = children;
symbols.push(ds);
}
else if (/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/.test(ltxt)) {
let result = txt.match(/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
let sname = result[1].trim();
let detail = "";
if(result.length == 3){
detail = "(" + result[2].trim() + ")";
}
symbols.push(new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Function, line.range, line.range));
}
}
resolve(symbols);
});
}
}

Remove All Items from NSDictionary/Dictionary where value == -1.0

I am migrating my data from 1 format to another for a large update to one of my iOS apps. This means that when a user updates their application it migrates their data to a new location. This new location has much stricter rules and uses proper practices (basically when I first created the app I was a noob and there are bad practices currently in the database and this new location is for good data only).
I have everything migrating nicely and everything works except I need to do one last thing. The large dictionary that I save to the database (it uses firebase fyi) has -1.0 stored everywhere there should be a nil value (bad, I know). What I need to do is loop through the entire dictionary and remove any key where the value of that key is -1.0.
The Dictionary is of type [AnyHashable : Any] which is what firebase uses.
I have tried this so far.
if let data = dataDictionary as? [AnyHashable : Any] {
let foundItems = data.filter { $0.value as? Double == -1.0 }
print(foundItems)
}
the plan was to then loop through that found items array and remove any key from the data dictionary that contained it.
This is what the data dictionary looks like:
"-KpIdh_TQMG4fyfFgkdt" = {
assignments = {
"-KpIgH6uN19OpcuedYe1" = {
assignmentGoal = "-1";
assignmentName = "Information System Proposal";
assignmentResult = 100;
assignmentWeight = 5;
};
"-KpIgJnFlC6fhgS0NWxF" = {
assignmentGoal = "-1";
assignmentName = "Information System";
assignmentResult = "-1";
assignmentWeight = 35;
};
"-KpIgOGSAwg_VSpDWhWR" = {
assignmentGoal = "-1";
assignmentName = "Process Analysis";
assignmentResult = "-1";
assignmentWeight = 30;
};
"-KpIgPhu_3Zxw36xt3O4" = {
assignmentGoal = "-1";
assignmentName = Labs;
assignmentResult = "-1";
assignmentWeight = 10;
};
"-KpIgQoFEdRnLlMAq2VN" = {
assignmentGoal = "-1";
assignmentName = Exam;
assignmentResult = "-1";
assignmentWeight = 20;
};
};
paperColor = 22;
paperGoal = 95;
paperName = "Systems Analysis";
};
};
semesterCode = 17S2;
semesterGoal = 90;
semesterName = "2017 Semester Two";
};
};
and this is what it should look like
"-KpIdh_TQMG4fyfFgkdt" = {
assignments = {
"-KpIgH6uN19OpcuedYe1" = {
assignmentName = "Information System Proposal";
assignmentResult = 100;
assignmentWeight = 5;
};
"-KpIgJnFlC6fhgS0NWxF" = {
assignmentName = "Information System";
assignmentWeight = 35;
};
"-KpIgOGSAwg_VSpDWhWR" = {
assignmentName = "Process Analysis";
assignmentWeight = 30;
};
"-KpIgPhu_3Zxw36xt3O4" = {
assignmentName = Labs;
assignmentWeight = 10;
};
"-KpIgQoFEdRnLlMAq2VN" = {
assignmentName = Exam;
assignmentWeight = 20;
};
};
paperColor = 22;
paperGoal = 95;
paperName = "Systems Analysis";
};
};
semesterCode = 17S2;
semesterGoal = 90;
semesterName = "2017 Semester Two";
};
};
The solution I have is to map (iterate) over each parent key and assign it's child nodes to a variable child. Then test each child property (assignmentGoal, assignmentName etc) for either "-1" for the string and -1 for the ints. If it's a match, remove that key: value pair from child.
Then assign child back to the parent node.
let result: [Any] = dict.map { dictionary in
var d = dictionary
var child = d.value as Dictionary
if let goal = child["assignmentGoal"] as? String, goal == "-1" {
child.removeValue(forKey: "assignmentGoal")
}
if let name = child["assignmentName"] as? String, name == "-1" {
child.removeValue(forKey: "assignmentName")
}
if let result = child["assignmentResult"] as? Int, result == -1 {
child.removeValue(forKey: "assignmentResult")
}
if let weight = child["assignmentWeight"] as? Int, weight == -1 {
child.removeValue(forKey: "assignmentWeight")
}
d.value = child
return d
}
//show the output
for item in result {
print(item)
}
and the result output
(key: "-KpIgOGSAwg_VSpDWhWR",
value: ["assignmentName": "Process Analysis System", "assignmentWeight": 30])
(key: "-KpIgQoFEdRnLlMAq2VN",
value: ["assignmentName": "Exam", "assignmentWeight": 20])
(key: "-KpIgJnFlC6fhgS0NWxF",
value: ["assignmentName": "Information System", "assignmentGoal": "3", "assignmentWeight": 35])
(key: "-KpIgPhu_3Zxw36xt3O4",
value: ["assignmentName": "Labs", "assignmentWeight": 10])
(key: "-KpIgH6uN19OpcuedYe1",
value: ["assignmentName": "Information System Proposal", "assignmentResult": 100, "assignmentWeight": 5])

Swift iOS application not saving all object Parse

My problem is adding new numbers to the array field in users. all the code seems to work but i have the problem with saveAll function. All the names are correct, as i've checked on several different occasions.
func taskAllocation(){
var query = PFUser.query()
var objectQuery:[PFUser] = [PFUser]()
query.whereKey("Year", equalTo: yearTextField.text.toInt())
query.whereKey("Class", equalTo: classTextField.text.toInt())
query.whereKey("Keystage", equalTo: keystageTextField.text.toInt())
query.findObjectsInBackgroundWithBlock { (objects: [AnyObject]!, error: NSError!) -> Void in
if error != nil {
println(error)
} else {
if objects.isEmpty {
println("empty query")
}
else {
for object in objects as [PFUser] {
var test:[Int] = object["taskIDs"] as [Int]
test.append(self.getIndex)
println(test)
object["taskIDs"] = test
object["tasksCompleted"] = "hello"
objectQuery.append(object)
}//For
println(objectQuery.count)
if objectQuery.count != 0{
println("Success!!!")
println(objectQuery)
PFUser.saveAllInBackground(objectQuery)
}
}
}
}
This below is stored in the println(objectQuery) as you can see the taskIDs have been appended and the tasksCompleted contains the string. Which leads me to believe that there is a problem with the saveallinbackground function.
[<PFUser: 0x155f6510, objectId: W6TrPQwCQ7, localId: (null)> {
Class = 2;
Forename = "Joe ";
Keystage = 2;
Surname = Freeston;
Year = 4;
admin = false;
completedTaskIDs = (
);
taskIDs = (
0,
2,
4,
5,
6,
46
);
tasksCompleted = hello;
tasksCorrect = 0;
userType = Student;
username = jfreeston;
}, <PFUser: 0x1569b7a0, objectId: slLd1KBIaM, localId: (null)> {
Class = 2;
Forename = "Camilla ";
Keystage = 2;
Surname = Linhart;
Year = 4;
admin = false;
completedTaskIDs = (
);
taskIDs = (
0,
46
);
tasksCompleted = hello;
tasksCorrect = 0;
userType = Student;
username = clinhart;
}]
Not sure if anyone has more knowledge of the parse api, mainly how the saveall/saveallinbackground functions work maybe.
To save all in background as a user I would first create a PFUser variable, like
var NewUser = PFUser.currentUser
Then to save in background
newUser.saveInBackgroundWithBlock {
(success:Bool, error: NSError!) -> Void in {
}
Then you can put if-statements and stuff within those brackets to do what you need it to when successful. like:
if(success) {
performSegueWithIdentifier("YourSegue", sender: nil)
}

Append divs changing his content dynamic

I have a dif called cdefualt that has some inputs from a form inside of it and I want to do something like this to clone it and change that input names:
var i = 2;
function add() {
var item = $('#cdefault').clone();
item.attr({'style': ''});
$xpto = 'gtitle'+i;
$xpto2 = 'gmessage'+i;
item.id = $xpto;
$('#'+$xpto+' input[id="gtitle1"]').attr('name', $xpto);
$('#'+$xpto+' textarea[id="gmessage1"]').attr('name',$xpto2);
$(item).appendTo('#ccontainer');
i++;
}
But this doesnt work. I've tried this already as well but it only works twice (for the original and first clone):
var i = 2;
function add() {
var item = $('#cdefault').clone();
item.attr({'style': ''});
$xpto = 'gtitle'+i;
$xpto2 = 'gmessage'+i;
$('#cdefault input[id="gtitle1"]').attr('id', $xpto);
$('#cdefault textarea[id="gmessage1"]').attr('id',$xpto2);
$('#cdefault input[name="gtitle1"]').attr('name', $xpto);
$('#cdefault textarea[name="gmessage1"]').attr('name', $xpto2);
$(item).appendTo('#ccontainer');
i++;
}
Even tryed this way:
function add() {
$xpto = 'gtitle'+i;
$xpto2 = 'gmessage'+i;
var div = document.getElementById('cdefault');
clone = div.cloneNode(true); // true means clone all childNodes and all event handlers
clone.id = $xpto;
clone.style.display = '';
$("#"+$xpto+" input[id='gtitle1']").attr('name', $xpto);
$("#"+$xpto+" textarea[id='gmessage1']").attr('name',$xpto2);
document.getElementById('ccontainer').appendChild(clone);
i++;
}
http://jsfiddle.net/Theopt/xNfSd/
fixed. changed cdefault id to id0 and this java script:
var i = 2;
var c = 0;
function add() {
$xpto = 'gtitle'+i;
$xpto2 = 'gmessage'+i;
var klon = $( '#id'+ c );
klon.clone().attr('id', 'id'+(++c) ).insertAfter( '#inserthere' );
document.getElementById('id'+(c)).style.display = '' ;
$("#id"+(c)+" input[id='gtitle1']").attr('name', $xpto);
$("#id"+(c)+" textarea[id='gmessage1']").attr('name',$xpto2);
i++;
}

objectAtIndex in NSDictionary

I am trying to create UITableView from my NSDictionary, but how can I use objectForKey? Convert to NSArray?
I need help.
My dictionary looks like:
**
{
"allow_comments" = 1;
category = 1024194;
"created_at" = "2011-11-17T01:44";
forum = 1005401;
"forum_obj" = {
"created_at" = "2011-09-03 03:04:43.514514";
description = "";
id = 1005401;
name = smartfiction;
shortname = smartfiction;
};
hidden = 0;
id = 474530565;
identifier = (
"2507 http://smartfiction.ru/?p=2507"
);
"num_comments" = 2;
slug = "thread_9714";
title = "\U041e\U0440\U0438\U0444\U043b\U0430\U043c\U043c\U0430. \U042d\U0436\U0435\U043d \U0418\U043e\U043d\U0435\U0441\U043a\U043e";
url = "http://smartfiction.ru/prose/oriflamma/";
}
2011-11-19 10:21:25.992 ARSSReader[3067:15503] id 474530565
2011-11-19 10:21:26.864 ARSSReader[3067:15503] Ответ #2: (
{
author = {
avatar = {
cache = "http://www.gravatar.com/avatar.php?gravatar_id=af6c6f08e213427ad611b00589db00f9&size=32&default=http://mediacdn.disqus.com/1321567697/images/noavatar32.png";
permalink = "http://www.gravatar.com/avatar.php?gravatar_id=af6c6f08e213427ad611b00589db00f9&size=32&default=http://mediacdn.disqus.com/1321567697/images/noavatar32.png";
};
emailHash = af6c6f08e213427ad611b00589db00f9;
isAnonymous = 1;
name = "S Shv";
profileUrl = "http://disqus.com/guest/af6c6f08e213427ad611b00589db00f9/";
url = "";
};
createdAt = "2011-11-17T22:39:36";
dislikes = 0;
forum = smartfiction;
id = 367003621;
isApproved = 1;
isDeleted = 0;
isEdited = 0;
isFlagged = 0;
isHighlighted = 0;
isJuliaFlagged = 1;
isSpam = 0;
likes = 0;
media = (
);
message = "\U043f\U043e\U0440\U0430\U0437\U0438\U043b\U043e )";
parent = "<null>";
points = 0;
"raw_message" = "\U043f\U043e\U0440\U0430\U0437\U0438\U043b\U043e )";
thread = 474530565;
},
{
author = {
avatar = {
cache = "http://www.gravatar.com/avatar.php?gravatar_id=c1c53088e04a60aab74cd1f149117e69&size=32&default=http://mediacdn.disqus.com/1321567697/images/noavatar32.png";
permalink = "http://www.gravatar.com/avatar.php?gravatar_id=c1c53088e04a60aab74cd1f149117e69&size=32&default=http://mediacdn.disqus.com/1321567697/images/noavatar32.png";
};
emailHash = c1c53088e04a60aab74cd1f149117e69;
isAnonymous = 1;
name = "3,14";
profileUrl = "http://disqus.com/guest/c1c53088e04a60aab74cd1f149117e69/";
url = "";
};
createdAt = "2011-11-17T02:52:46";
dislikes = 0;
forum = smartfiction;
id = 365544459;
isApproved = 1;
isDeleted = 0;
isEdited = 0;
isFlagged = 0;
isHighlighted = 0;
isJuliaFlagged = 1;
isSpam = 0;
likes = 1;
media = (
);
message = "\U0427\U0438\U0442\U0430\U0442\U044c \U043d\U0430 \U043d\U043e\U0447\U044c \U043f\U0440\U043e\U043a\U0440\U0430\U0441\U0442\U0438\U043d\U0430\U0442\U043e\U0440\U0430\U043c. \U0412\U043f\U0440\U043e\U0447\U0435\U043c, \U043b\U0443\U0447\U0448\U0435 \U0443\U0442\U0440\U043e\U043c.";
parent = "<null>";
points = 1;
"raw_message" = "\U0427\U0438\U0442\U0430\U0442\U044c \U043d\U0430 \U043d\U043e\U0447\U044c \U043f\U0440\U043e\U043a\U0440\U0430\U0441\U0442\U0438\U043d\U0430\U0442\U043e\U0440\U0430\U043c. \U0412\U043f\U0440\U043e\U0447\U0435\U043c, \U043b\U0443\U0447\U0448\U0435 \U0443\U0442\U0440\U043e\U043c.";
thread = 474530565;
}
)
**
It is comments from disqus.com. I want to create dictionaries for all comments and use them to create UITableView cells.
Instead of storing the comments from disqus.com in a dictionary, store each comment in an entry inside an array (it looks like each comment has a block of text you can encapsulate into an object which you can store into an array).
Dictionaries are good for associating values with keys.
Arrays are great for storing lists of objects, much like a list of comments from a disqus site.